题目描述(简单动态递归)
https://leetcode-cn.com/problems/maximum-subarray/
解法
以思考动态递归的通用过程去思考问题,一般求最大的子序和,或者最大递增序列什么的,都是定义dp[i]表示以i结尾的最大…去思考。
然后思考递推方程,用实例,然后自己去试着从0开始一个一个推,得到方程
第三步,思考边界情况
最后思考结果返回。
第一次代码:
class Solution {
public int maxSubArray(int[] nums) {
if(nums==null) return 0;
int []dp = new int[nums.length];//表示以i结尾的最大连续子序和
//边界
dp[0]=nums[0];
int max = dp[0];
for(int i=1;i<nums.length;i++){
if(dp[i-1]<0){
dp[i]=nums[i];
}else
dp[i]=dp[i-1]+nums[i];
//保存最大值
if(dp[i]>max){
max = dp[i];
}
}
return max;
}
}
进行状态压缩:
因为只与两个状态有关,所以我们可使用类似滚动数组的方式去做:
class Solution {
public int maxSubArray(int[] nums) {
if(nums==null) return 0;
//边界
int dp_pre=nums[0], dp_now=nums[0];//状态压缩
int max = nums[0];
for(int i=1;i<nums.length;i++){
if(dp_pre<0){
dp_now=nums[i];
}else
dp_now=dp_pre+nums[i];
//更新dp_pre
dp_pre = dp_now;
//保存最大值
if(dp_now>max){
max = dp_now;
}
}
return max;
}
}
我记得我之前学分治的时候,做过这道题…好像可以用分治法,维护左边最大子序和右边最大子序,然后当前的最大子序要么来自左边要么来自右边,要么两个部分相加。
- 关于左边最大子序,是指从分界点往左走的最大连续子序
- 关于右边最大子序,是指从分界点往右走的最大连续子序
等我刷分治法的时候,再来更新了。