这道题很好想的是遍历,二重循环O(n^2)复杂度,挨个算每种情况,找最大的,然而这样子会超时间.....
比较典型的解法,分治法,就是一个数组,求最大的连着几个的和,可能在左边,也可能在右边,还可能在中间,所以用分治法递归,。递归的药店要点,确定基准,向着基准推进,所有的递归都能运行,不在在不同的递归里不能进行同样的重复的运算。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
return maxSub(nums,0,nums.size()-1);
}
private:
int maxSub(const vector<int>& nu,int left,int right)
{
if(left==right)
{
return nu[left];
}
int mid=(left+right)/2;
int maxleft=maxSub(nu,left,mid);
int maxright=maxSub(nu,mid+1,right);
int maxmidleft=nu[mid];
int maxmidright=nu[mid+1];
int temp=0;
for(int i=mid;i>=left;i--)
{
temp+=nu[i];
if(temp>maxmidleft)
{
maxmidleft=temp;
}
}
temp=0;
for(int i=mid+1;i<=right;i++)
{
temp+=nu[i];
if(temp>maxmidright)
{
maxmidright=temp;
}
}
int maxmid=maxmidright+maxmidleft;
return max(max(maxleft,maxright),maxmid);
}
};
还有一种简便的,复杂度O(n)。这种的原则是,最优序列开头不是负的,因为如果开头是负的,那么去掉这个开头一定是更大的(如果所有元素都是负的就不这样想了)。然后就可以遍历一次搞定。
class Solution { public: int maxSubArray(vector<int>& nums) { int num=nums[0]; int numtemp=0; for(int i=0;i<nums.size();i++) { numtemp+=nums[i]; num=max(num,numtemp); numtemp=max(numtemp,0); } return num; } };