连续子数组的最大和
描述:
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
思路1:一维动规
特殊情况处理:数组长度为0,返回0,数组长度为1,返回1
动规4步:(1)确定状态:最后一步,dp[i]代表以元素nums[i] 为结尾的连续子数组最大和
(2)转移方程:若dp[i-1]>0,说明之前的结果会让子数组更大F[i]=F[i-1]+nums[i],否则不会更大就不加了F[i]=nums[i],定义变量max保存每一轮结果的最大值(因为nums[i]是必须加的(我们设的是i结尾最大),但是nums[i]可能小于0)所以判断最终每一轮都取max和dp[i]中大的值,返回max
(3)初始条件:数组只有一个元素,最大子数组就是自己本身
(4)执行顺序:每一步都用前一步的结果,从前往后
代码:
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = nums[0];
for(int i = 1; i < nums.length; i++){
if(dp[i-1] > 0){
dp[i] = dp[i-1] + nums[i];
}else{
dp[i] = nums[i];
}
max = Math.max(max,dp[i]);
}
return max;
}
}
思路2:在原数组上直接操作
dp就代表以nums[i]为数组尾部的子数组最大值,若dp大于0,就加上;否则不加dp从nums[i]重算,每一轮仍旧与max相比,大的给max,最后返回max
代码:
class Solution {
public int maxSubArray(int[] nums) {
int dp = nums[0];
int max = nums[0];
for(int i = 1; i < nums.length; i++){
if(dp > 0){
dp = dp + nums[i];
}else{
dp = nums[i];
}
max = Math.max(max,dp);
}
return max;
}
}