问题描述
给你一个整数数组nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
这里注意的一个点是,子数组 与 子序列。我们通常这样认为子数组是数组的连续子集,即使数组的切片。而子序列是数组的任意子集,即可以有数组里任意元素组合而成。
动态规划思路
状态定义
定义一维的dp
数组,dp[i]表示下标为i结尾的nums
数组最大连续子数组和,并维护一个全局的最大值res
。
状态转移逻辑
我们在累加元素时必须要考虑的是,如果累加当前元素nums[i]
之后大于当前元素nums[i]
,那么我们就更新子数组和为dp[i-1]+nums[i]
。反之就得从当前元素nums[i]
开始重新累加:
dp[i] = max(dp[i-1]+nums[i], nums[i])
初始值及特殊情况
由于递推公式中有i-1
,所以我们需要给dp[0]
赋初始值nums[0]
,一个数的数组子数组和就是他本身。遍历循环从i=1
开始。
代码
public static int maxSubArray(int[] nums) {
int res = nums[0];
int[] dp = new int[nums.length+1];
dp[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i-1]+nums[i], nums[i]);
res = Math.max(dp[i], res);
}
return res;
}