#剑指offer30连续子数组的最大和
连续子数组的最大和
https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=13&&tqId=11183&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
剑指offer30连续子数组的最大和
#剑指offer30
牛客题霸参考
1、动态规划
F[i]:表示以i位置结尾的连续子数组的最大和
状态方程:F[i]=max{F[i-1]+array[i],array[i]}
时间复杂度:O(n) 空间复杂度O(n)
个人代码参考
//动态规划 //F[i]:表示以i位置结尾的连续子数组的最大和 //状态方程:F[i]=max{F[i-1]+array[i],array[i]} int FindGreatestSumOfSubArray(vector<int> array) { vector<int>F(array.size(),0); F[0]=array[0]; int ret=F[0]; //记录F[]中最大值,即以记录以某k位置的连续子数组和的最大值 for(int i=1;i<array.size();i++) { F[i]=max(F[i-1]+array[i],array[i]); ret=max(ret,F[i]); } return ret; }
2、空间优化
时间复杂度:O(n) 空间复杂度O(1)
个人代码参考
class Solution { public: //动态规划 //F[i]:表示以i位置结尾的连续子数组的最大和 //状态方程:F[i]=max{F[i-1]+array[i],array[i]} //空间优化: //实际上并不需要保存所有以i位置结尾的连续子数组的最大和 //因为: //1、最终所求最大和的那个连续数组结尾位置的数一定大于0, //即以小于0元素为结尾的连续数组对结果没贡献 //2、求以k位置元素结尾连续数组最大和时,前面的以(<k位置结尾的)连续数组, //实际只需要是前面最大的那个最大和(连续数组),以及该连续数组结尾与k之间的累加值 int FindGreatestSumOfSubArray(vector<int> array) { int ret=0; //记录连续子数组最大值 int sum=0; //记录上一个最大的(连续子数组的)最大和到当前元素的累加值 int index=0; int Max=array[0]; while(index<array.size()&&array[index]<0)//找第一个最大和,显然是第一个大于零的元素 { Max=array[index]>Max?array[index]:Max; //顺便找到其中的最大值 ++index; } if(index==array.size()) //若全是小于0的元素,则返回最大值 return Max; ret=array[index];//第一个大于零的元素,显然就是第一个最大和 ++index; for(int i=index;i<array.size();i++) { sum+=array[i];//累加上一个最大和到当前元素 if(sum>0) //上一个最大和连续数组的结尾累加到当前元素的和>0,说明有了贡献值 { //以当前元素结尾的连续数组最大和肯定大于之前的最大和了 ret=max(ret+sum,array[i]);//以当前元素结尾的连续数组最大和的状态方程 sum=0; //更新最大和后重新累加 } } return ret; } };