输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
数据范围:
要求:时间复杂度为 ,空间复杂度为
进阶:时间复杂度为 ,空间复杂度为
[1,-2,3,10,-4,7,2,-5]
18
经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18
[2]
2
[-10]
-10
int FindGreatestSumOfSubArray(vector<int> array) { if(array.empty()) return 0; int cSum = 0; int result = array[0]; // result存储最大和,不能初始为0,存在负数 for(int i = 0;i<array.size();++i) { if(cSum < 0) // 当前和<0,抛弃不要 cSum = array[i]; else cSum += array[i]; if(cSum > result) // 存储最大结果 result = cSum; } return result; }
//直通BAT第二季 左神讲过 class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { if(array.size()<=0) return 0; int cur,res; cur=array[0]; //当前子向量和 res=cur; //存储最大的子向量和 for(int i=1;i<array.size();i++) { if(cur<0) cur=0; cur=cur+array[i]; if(cur>res) res=cur; } return res; } };
public int FindGreatestSumOfSubArray(int[] array) { int res = array[0]; //记录当前所有子数组的和的最大值 int max=array[0]; //包含array[i]的连续数组最大值 for (int i = 1; i < array.length; i++) { max=Math.max(max+array[i], array[i]); res=Math.max(max, res); } return res; }
/* C++ 循环 实现 思路:声明一个变量记录遇到的最大的一个值 isInvalidInput用来标记返回0是由于非法输入还是最大和为0 */ class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { bool isInvalidInput=false; if(array.size()==0) return 0; isInvalidInput=true; int maxSum=array[0],sum=array[0]; for(int i=1;i<array.size();i++) { if(sum>0) { sum+=array[i]; if(sum>maxSum) maxSum=sum; } else { if(array[i]>maxSum) maxSum=array[i]; sum=array[i]; } } return maxSum; } };
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { vector<int> dp(array.size()); dp[0] = array[0]; for(int i = 1, size = array.size(); i < size; i++) { dp[i] = max(array[i], array[i]+dp[i-1]); } return *max_element(dp.begin(), dp.end()); } };
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if(array.length==0) return 0; int[] d = new int[array.length]; d[0] = array[0]; int max = d[0]; for(int i=1;i<array.length;i++){ if(d[i-1]<=0){ d[i] = array[i]; }else{ d[i] = d[i-1]+array[i]; } if(d[i]>max) max = d[i]; } return max; } }
时间复杂度O(n),空间复杂度O(1)
class Solution { public: //相当于array在遍历的过程中充当了存储当前最大数的角色 int FindGreatestSumOfSubArray(vector<int> array) { if(array.size()==1) return array[0]; int ans = INT_MIN; for(int i=1;i<array.size();i++){ //当前数 和 当前数+前面的累加最大数 求max array[i] = max(array[i],array[i]+array[i-1]); ans = max(ans,array[i]); } return ans; } };
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { int n = array.length; int max = 0, i = 0, result = Integer.MIN_VALUE; while(i < n) { max = max + array[i]; result = Math.max(result, max); if(max < 0) max = 0; i++; } return result; } }
贪心算法
两个序列,A是容忍负数出现的序列,B是不容忍负数出现的序列;
①A每轮选择A和B中值最大的,然后加上当前的数字,无论正负;
②B每轮的选择是,如果B当前数字 >=0 且当前的数字 >0,则自身加上当前数字,否则等于当前数字(这使得B有些名不副实,不过它可以应对全部都是负数的情况)。
③max作为一个统计值,每轮取它自身和A、B3者中最大的一个。
public int FindGreatestSumOfSubArray(int[] array) { int allowNegative = 0, notAllowNegative = 0, max = array[0]; for (int num : array) { int tmp = allowNegative > notAllowNegative ? allowNegative : notAllowNegative; allowNegative = tmp + num; notAllowNegative = num > 0 && notAllowNegative >= 0 ? notAllowNegative + num : num; max = allowNegative > max ? allowNegative : max > notAllowNegative ? max : notAllowNegative; } return max; }
把全负的考虑了 class Solution: def FindGreatestSumOfSubArray(self, array): # write code here sumslst = [] lens = len(array) if lens < 1: return None if max(array) < 0: return max(array) for i in range(lens): while lens > 0: sums = 0 for j in range(i, lens): sums += array[j] sumslst.append(sums) lens -= 1 lens = len(array) return max(sumslst)
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { int thisSum,maxSum; int size=array.size(); thisSum=0; maxSum=array[0]; for(int j=0;j<size;j++){ thisSum+=array[j]; if(thisSum>maxSum) maxSum=thisSum; else if(thisSum<0) thisSum=0; } return maxSum; } };
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { if(array.length==0)return 0; for(int i = 1 ; i < array.length; i++) if(array[i-1]>0) array[i] += array[i-1]; int max = array[0]; for(int i = 1 ; i < array.length; i++) if(array[i] > max)max = array[i]; return max; } }
现在拿n个向量测试,发现结果大多为负,最大的一个是0,Okay,我找到了,然后翻出来一看,这个向量是空的。。。 现在拿n个向量测试,发现n个结果都是0,第一个向量全是0,第二个向量是空的。。。 class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { if(array.size()==0) return 0; vector<int> dp(array); int re=dp[0]; for(int i=1;i<array.size();i++){ if(dp[i-1]>0) dp[i]=dp[i-1]+array[i]; else dp[i]=array[i]; if(dp[i]>re) re=dp[i]; } return re; } };
class Solution { public: int FindGreatestSumOfSubArray(vector<int> array) { int len = array.size(); if(len <= 0) return 0; if(len == 1) return array[0]; vector<int> dp(len,0); dp[0] = array[0]; int m = array[0]; for(int i = 1; i < len; i ++){ dp[i] = max(dp[i-1]+array[i],array[i]); m = max(dp[i],m); } return m; } };简单dp
public int FindGreatestSumOfSubArray(int[] array) { if(array==null||array.length==0) return 0; int sum=0,maxsum=Integer.MIN_VALUE; for (int i = 0; i < array.length; i++) { sum+=array[i]; if(sum>maxsum)maxsum=sum; if(sum<0)sum=0; } return maxsum; }
//动态规划 int FindGreatestSumOfSubArray(vector<int> array) { if(array.empty()) return 0; int sum = array[0], tempsum = array[0]; //注意初始值 不能设为0 防止只有负数 for(int i = 1; i < array.size(); i++) //从1开始 因为0的情况在初始化时完成了 { tempsum = (tempsum < 0) ? array[i] : tempsum + array[i]; sum = (tempsum > sum) ? tempsum : sum; } return sum; }
public class Solution { public int FindGreatestSumOfSubArray(int[] array) { int sum = array[0]; int former = 0; //用于记录dp[i-1]的值 int cur = 0;//用于记录dp[i]的值 for(int arr : array) { cur = arr; cur += Math.max(former, 0); sum = Math.max(sum, cur); former = cur; } return sum; } }