Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4]
,
the contiguous subarray [4,−1,2,1]
has the largest sum = 6
.
这道题是求最大连续字数组和的问题,首先容易想到的是暴力求解:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int nSize=nums.size();
int max=nums[0];
for(int i=0;i<nSize;i++)
{
for(int j=i;j<nSize;j++)
{
int temp=0;
for(int k=i;k<j;k++)
{
temp+=nums[k];
}
if(temp>max)
max=temp;
}
}
return max;
}
};
上边算法的时间复杂度为O(n^3)
对暴力求解改进一下,可以降低时间复杂度,
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int nSize=nums.size();
int max=nums[0];
for(int i=0;i<nSize;i++)
{
int temp=0;
for(int j=i;j<nSize;j++)
{
temp+=nums[j];
if(temp>max)
max=temp;
}
}
return max;
}
};
虽然列出来两种暴力求解的方法,不过,由于时间复杂度太高,都没有被LeetCode所AC;
用一种动态规划的思路可以降低时间复杂度,
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int endHere=nums[0];
int res=nums[0];
for(int i=1;i<nums.size();i++)
{
if(endHere>0)
endHere=endHere+nums[i];
else
endHere=nums[i];
if(res<endHere)
res=endHere;
}
return res;
}
};
还有一种思路,我们考虑使用前缀和,记录最小的前缀和,我们可以认为两个前缀和的差就是一段连续字数组的和
class Solution {
public:
int min(int a,int b)
{
if(a<b)
return a;
else
return b;
}
int max(int a,int b)
{
if(a<b)
return b;
else
return a;
}
int maxSubArray(vector<int>& nums) {
int sum=nums[0];
int minsum=min(0,sum);
int res=nums[0];
for(int i=1;i<nums.size();i++)
{
sum+=nums[i];
res=max(res,sum-minsum);
minsum=min(minsum,sum);
}
return res;
}
};