给定一个整数数组 nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
动态规划解法
思路:
1.状态方程:dp[i]=Max(dp[i-1]+A[i],A[i])
2.我们从头开始遍历数组,遍历到数组元素 arr[ i ] 时,连续的最大的和 可能为 max( dp[ i -1 ] ) + arr[ i ] ,也可能为 arr[ i ] ,做比较即可得出哪个更大,取最大值。时间复杂度为O(N)
public static int maxSubarraySum(int[] A) {
int max=A[0];
int[] dp=new int[A.length];
dp[0]=A[0];
for(int i=1;i<A.length;i++){
dp[i]=Math.max(dp[i-1]+A[i], A[i]);
if(dp[i]>max)
max=dp[i];
}
return max;
}
非动规解法1
思想和动规方法相似。对数组元素进行累加,每累加一个数,比较加上当前的数的和与当前这个数谁大,就将累加和设为谁。
例如:1,-2, 3
第一步:sum=1,max=1
第二步:加上-2,sum=-1 >-2,所以累加和就是-1,max不变
第三步:加上3,sum=2<3,此时我们发现加上前面的反而会使和变小,所以这个时候,就要把累加和设为3,也就是从3开始重新累加,max=3
public static int maxSubarraySum(int[] A) {
int max=A[0];
int sum=A[0];
for(int i=1;i<A.length;i++){
if(sum+A[i]<A[i]){
sum=A[i];
}else {
sum+=A[i];
}
if (sum>max) {
max=sum;
}
}
return max;
}
非动规解法2
public static int maxSubarraySum(int[] A) {
int max=Integer.MIN_VALUE;
int sum=0;
for (int i = 0; i < A.length; i++) {
max=Math.max(max, sum+A[i]);
if(sum+A[i]>0){
sum+=A[i];
}else {
sum=0;
}
}
return max;
}