- 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
详细讲解见我的另一篇博客
代码:
#define Max(a,b) ((a)>(b)?(a):(b))
int maxSubArray(int* nums, int numsSize){
if(numsSize==0)
return 0;
int dp[numsSize];
int max = nums[0];
dp[0]=nums[0];
for(int i=1;i<numsSize;i++)
{
dp[i]=Max(dp[i-1]+nums[i],nums[i]);
max=Max(dp[i],max);
}
return max;
}
当然或许会有另一种设法,即我们设dp[i]为有i个数时其最大子序列的大小。
这样类似的我们可以得到下列代码:
int max(int a,int b,int c)
{
int temp = a>b?a:b;
return temp>c?temp:c;
}
int maxSubArray(int* nums, int numsSize){
if(numsSize==0)
return 0;
int dp[numsSize+1];
dp[1]=nums[0];
for(int i=2;i<=numsSize;i++)
{
dp[i]=max(dp[i-1]+nums[i-1],nums[i-1],dp[i-1]);//会出现不连续的情况
}
return dp[numsSize];
}
但我们会发现不对的地方,即由于我们的dp[i]只是代表有i个数时其最大子序列的大小,并不是一定包含第i个数,因此代码中的dp[i-1]+nums[i-1]此时就不一定是连续的了。所以不可这样写。而我们先前那个之所以可以是因为我们定义了以下标i为结尾了,所以一定连续。
滚动数组优化:
int Max(int x,int y)
{
return x>y?x:y;
}
int maxSubArray(int* nums, int numsSize){
if(numsSize==0)
return 0;
int first,second;
first=nums[0];
int max = first;
for(int i=1;i<numsSize;i++)
{
second=Max(first+nums[i],nums[i]);
max=Max(second,max);
first=second;
}
return max;
}