链接:https://leetcode-cn.com/problems/maximum-subarray/
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:
如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
思路:
利用动态规划进行解题,题目要求最大和的连续子数组,那么求解当前最大子序和的时候,只与当前值nums[i]
和前面的最大数值dp[i-1]+nums[i]
进行比较,再取出最大值。
使用dp[i]表示以第i个数结尾的最大和的连续子数组的和,得出状态转移方程:
dp[i] = max(nums[i]+dp[i-1], nums[i])
代码:
class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
int len = nums.length;
int[] dp = new int[len+1];
dp[0] = 0;
int res = Integer.MIN_VALUE;
for(int i=1; i<=len; i++){
dp[i] = Math.max(nums[i-1]+dp[i-1], nums[i-1]);
res = Math.max(res, dp[i]);
}
return res;
}
}
优化:
- 因为每次只和当前值与上一个值有关
class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
// 优化,因为每次只和当前值与上一个值有关
int len = nums.length;
int curr = 0;
int res = Integer.MIN_VALUE;
for(int i=0; i<len; i++){
curr = Math.max(nums[i]+curr, nums[i]);
res = Math.max(curr, res);
}
return res;
}
}