JZ30 连续子数组的最大和
题目描述:
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
示例:
输入:
[1,-2,3,10,-4,7,2,-5]
返回值:
18
说明:
输入的数组为{1,-2,3,10,—4,7,2,一5},和最大的子数组为{3,10,一4,7,2},因此输出为该子数组的和 18。
题解:
方法一:动态规划
1.思路
动态规划的常规题
状态定义:dp[i]表示前i个的连续子数组的最大和。所以最终要求dp[n]
状态转移方程:dp[i] = max(array[i-1], dp[i-1]+array[i-1])。因为第i个数组的坐标为i-1
初始状态: dp[0]=0;此时没有元素
2.复杂度:
时间复杂度:O(n)
空间复杂度:O(n)
3.代码:
import java.util.*;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
// 方法一:dp
int len = array.length;
int[] dp = new int[len+1];
dp[0] = 0;
int max = array[0];
for(int i=1; i<=len; i++){
dp[i] = Max(dp[i-1]+array[i-1], array[i-1]);
max = Max(max, dp[i]);
}
return max;
}
int Max(int a,int b){
if(a>b)
return a;
else
return b;
}
}
方法二:
1.思路
思想很简单,就是对下标为i的元素array[i],先试探的加上array[i], 如果和为负数,显然,以i结尾的元素对整个结果不作贡献。
具体过程:
初始化:维护一个变量sum= 0
如果sum+array[i] < 0, 说明以i结尾的不作贡献,重新赋值tmp = 0
否则更新sum= sum+ array[i]
然后用一个变量max 更新最值
2.复杂度:
时间复杂度:O(n)
空间复杂度:O(1)
3.代码:
import java.util.*;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
// 方法二:
int len = array.length;
int sum = 0;
int max = array[0];
for(int i=0; i<len; i++){
if(sum + array[i] < 0){
max = Max(max, sum+array[i]);
sum = 0;
}
else{
sum += array[i];
max = Max(max, sum);
}
}
return max;
}
int Max(int a,int b){
if(a>b)
return a;
else
return b;
}
}