【算法07】求子数组的最大和
2011-11-30 14:38
239 查看
题目:输入一个整型数组,数组里面有正数也有负数,数组中的连续一个或者多个整数组成一个子数组,每一个子数组都有一个和,求所有子数组和的最大值。要求时间复杂度为O(n)。
例如:输入数组为{1,-2,3,10,-4,7,2,-5},和的最大子数组为{3,10,-4,7,2},因此输出为子数组的和18。
分析1:一般地,对于在整体集合内寻找满足某一条件子集合问题,最直观也最后理解的方法就是——枚举,求出所有子数组的和,然后比较求出最大的值,即可。然而对于长度为n的数组,它的子数组共有n(n-1)/2个,O(n^2),然后再对于每一个数组求和,时间复杂度为O(n)。因此总的时间复杂度为O(n^3)。效率太低。
分析2:我们知道,对于某个子数组,如果它的下一个数为正数,加上该正数和会增加;而加上一个负数,和会减少;如果当前子数组的话为负数,下一个数不论是正数还是负数,都会使得子数组的和进一步减少,因而这时候应该将子数组和重置为0。基于这种思路我们可以写出如下的代码:
关于上述代码有两点需要注意:
(1)如果一个数组中的数全部都是负数,那么这时候largestSum还是初始值0,而这时候整个数组的子数组和的最大值就是数组中的最大元素,因而单独拿出来考虑。
(2)关于函数的返回类型,如果按照正常的考虑,函数的返回值应该为整型,即范围子数组和的最大值,然而这样存在一个问题,如果输入本身的无效值,返回什么?返回0,那么如果数组中有0元素,其余全是负数元素,这时候0代表无效输入还是最大值?返回-1?数组中的最大元素真的是-1,怎么办?综上考虑,把子数组和的最大值以引用的方式传入函数的参数,同时让函数范围一个处理正常与否的标志,应该是比较好的方式(何海涛博主的考虑方式很严谨。)
References:
何海涛博客:http://zhedahht.blog.163.com/blog/static/254111742007219147591/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
例如:输入数组为{1,-2,3,10,-4,7,2,-5},和的最大子数组为{3,10,-4,7,2},因此输出为子数组的和18。
分析1:一般地,对于在整体集合内寻找满足某一条件子集合问题,最直观也最后理解的方法就是——枚举,求出所有子数组的和,然后比较求出最大的值,即可。然而对于长度为n的数组,它的子数组共有n(n-1)/2个,O(n^2),然后再对于每一个数组求和,时间复杂度为O(n)。因此总的时间复杂度为O(n^3)。效率太低。
分析2:我们知道,对于某个子数组,如果它的下一个数为正数,加上该正数和会增加;而加上一个负数,和会减少;如果当前子数组的话为负数,下一个数不论是正数还是负数,都会使得子数组的和进一步减少,因而这时候应该将子数组和重置为0。基于这种思路我们可以写出如下的代码:
#include<iostream> #include<string> using namespace std; bool FindMaxSubarray(int *pArray,int arrayLength,int &largestSum) { //无效输入,返回false if(pArray == NULL || arrayLength <= 0) return false; int curSum = 0; largestSum = 0; for(int i = 0;i < arrayLength;++i) { curSum += pArray[i]; //如果当前和小于0,重置为0 if(curSum < 0) curSum = 0; //找到更大的和,用largestSum保存 if(curSum > largestSum) largestSum = curSum; } //如果所有的数为都是小于等于0,找到该数组最大的数 if(largestSum == 0) { largestSum = pArray[0]; for(int i = 1;i < arrayLength;++i) { if(pArray[i] > largestSum) largestSum = pArray[i]; } } return true; } int main() { cout<<"Enter the length of your array:"<<endl; int n; cin>>n; cout<<"Enter the numbers in your array:"<<endl; int *p = new int ; for(int k = 0;k < n;++k) { cin>>p[k]; } cout<<"your array is:"<<endl; for(k = 0; k < n;++k) cout<<p[k]<<" "; cout<<endl; cout<<"the largest subarray sum is:"<<endl; int saveSum; FindMaxSubarray(p,n,saveSum); cout<<saveSum<<endl; return 0; }
关于上述代码有两点需要注意:
(1)如果一个数组中的数全部都是负数,那么这时候largestSum还是初始值0,而这时候整个数组的子数组和的最大值就是数组中的最大元素,因而单独拿出来考虑。
(2)关于函数的返回类型,如果按照正常的考虑,函数的返回值应该为整型,即范围子数组和的最大值,然而这样存在一个问题,如果输入本身的无效值,返回什么?返回0,那么如果数组中有0元素,其余全是负数元素,这时候0代表无效输入还是最大值?返回-1?数组中的最大元素真的是-1,怎么办?综上考虑,把子数组和的最大值以引用的方式传入函数的参数,同时让函数范围一个处理正常与否的标志,应该是比较好的方式(何海涛博主的考虑方式很严谨。)
References:
何海涛博客:http://zhedahht.blog.163.com/blog/static/254111742007219147591/
注:
1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。
2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。
相关文章推荐
- 算法题13 求子数组的最大和
- 微软算法100题03 求子数组的最大和
- 算法讨论(二)---求子数组的最大和
- 算法与数据结构面试题(3)-求子数组的最大和
- 每天一道算法题3 求子数组的最大和
- 人人都来写算法 之 求子数组的最大和
- 算法学习二----求子数组的最大和
- <跟着结构之法一起学算法>求子数组的最大和
- 微软等数据结构+算法面试100题(44)-- 求子数组的最大和
- 【算法之数组(一)】求子数组最大和的解决方法详解
- 每天一道算法题3 求子数组的最大和
- 数据结构与算法-求子数组的最大和
- 算法 - 求子数组的最大和(C++)
- 数据结构和算法设计专题之---求子数组和的最大值
- Java实现算法之--求子数组和的最大值
- 数据结构——算法之(006)(求子数组的最大和)
- 【算法总结-DP】求子数组的最大和
- Java实现算法之--求子数组和的最大值
- 【算法总结-DP】求子数组的最大和
- 微软100道算法题------求子数组的最大和