给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [0]
输出:0
示例 4:
输入:nums = [-1]
输出:-1
示例 5:
输入:nums = [-100000]
输出:-100000
提示:
1 <= nums.length <= 3 * 104
-105 <= nums[i] <= 105
不连续的情况
先抛开题目我们来寻找不连续的最大子序和:
#define Max(a,b) ((a)>(b)?(a):(b))
int maxSubArray(int* nums, int numsSize){
int *dp;
dp=(int *)calloc(numsSize,sizeof(int));
dp[0]=nums[0];
for(int i=1;i<numsSize;i++)
{
dp[i]=nums[i];
for(int j=0;j<i;j++)
dp[i]=Max(dp[i],Max(dp[j]+nums[i],dp[j]));
}
return dp[numsSize-1];
}
回归题目
①暴力枚举——算法复杂度O(n^2)
#include <stdio.h>
#include <stdlib.h>
int maxSubArray(int* nums, int numsSize)
{
int i,j;
int sum,max=-(2<<29);
for(i=0;i<numsSize;i++)
{
sum=0;
for(j=i;j<numsSize;j++)
{
sum+=nums[j];
if(sum>max)
max=sum;
}
}
return max;
}
int main()
{
int n,nums[1000];
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&nums[i]);
printf("%d",maxSubArray(nums,n));
return 0;
}
②贪心算法——算法复杂度O(n)
#include <stdio.h>
#include <stdlib.h>
int maxSubArray(int* nums, int numsSize)
{
int ans=nums[0];
int sum=nums[0];
for(int i=1;i<numsSize;i++)
{
if(sum<0)
sum=0;
sum+=nums[i];
if(sum>ans)
ans=sum;
}
return ans;
}
int main()
{
int n,nums[1000];
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&nums[i]);
printf("%d",maxSubArray(nums,n));
return 0;
}
③前缀和——算法复杂度O(n^2)
#include <stdio.h>
#include <stdlib.h>
#define Max(a,b) ((a)>(b)?(a):(b))
int maxSubArray(int* nums, int numsSize)
{
int *sub,i,j,max=-(2<<29);
sub=(int *)calloc(numsSize+1,sizeof(int));
for(i=1;i<=numsSize;i++)
sub[i]=sub[i-1]+nums[i-1];
for(i=0;i<=numsSize;i++)
for(j=i+1;j<=numsSize;j++)
max=Max(max,sub[j]-sub[i]);
return max;
}
int main()
{
int n,nums[1000];
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&nums[i]);
printf("%d",maxSubArray(nums,n));
return 0;
}