题目描述:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
三种思路
1.暴力破解
复杂度高达O(n^3),且思路复杂,不表。
2.分治
复杂度(nlogn),比较好理解。思路:

最后只需取三者中的最大值。
最初WA了两发,代码如下:
class Solution {
public:
int maxSubArray(vector<int>& nums)
{return max(nums,0,nums.size()-1);}
int max(vector<int>& nums,int left,int right)
{
int sum;
int s;
int leftsum,rightsum=0;
if(left==right)
{
sum=nums[left];
}
else
{
int center=(left+right)/2;
leftsum=max(nums,left,center);
rightsum=max(nums,center+1,right);
int s1=0;int s2=0;
int lefts=0;int rights=0;
for(int j=center;j>=left;j--)
{
lefts+=nums[j];
if(lefts>s1)
s1=lefts;
}
for(int k=center+1;k<=right;k++)
{
rights+=nums[k];
if(rights>s2)
s2=rights;
}
s=s1+s2;
sum=s;
if(leftsum>sum)
sum=leftsum;
if(rightsum>sum)
sum=rightsum;
}
return sum;
}
};
问题:值全为负时,显然返回的值仍是s1与s2之和,因为初始值为0,比期待输出的sum值要大,于是修改s1,s2为极大负数:
class Solution {
public:
int maxSubArray(vector<int>& nums)
{return max(nums,0,nums.size()-1);}
int max(vector<int>& nums,int left,int right)
{
int sum;
int s;
int leftsum,rightsum=0;
if(left==right)
{
sum=nums[left];
}
else
{
int center=(left+right)/2;
leftsum=max(nums,left,center);
rightsum=max(nums,center+1,right);
int s1=-30000;int s2=-30000;
int lefts=0;int rights=0;
for(int j=center;j>=left;j--)
{
lefts+=nums[j];
if(lefts>s1)
s1=lefts;
}
for(int k=center+1;k<=right;k++)
{
rights+=nums[k];
if(rights>s2)
s2=rights;
}
s=s1+s2;
sum=s;
if(leftsum>sum)
sum=leftsum;
if(rightsum>sum)
sum=rightsum;
}
return sum;
}
};
运行结果:

时间空间得到极大优化。
3.动态规划
不表
276

被折叠的 条评论
为什么被折叠?



