LeetCode53、最大子序和

题目描述(简单动态递归)

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;
    }
}

在这里插入图片描述

我记得我之前学分治的时候,做过这道题…好像可以用分治法,维护左边最大子序和右边最大子序,然后当前的最大子序要么来自左边要么来自右边,要么两个部分相加。

  • 关于左边最大子序,是指从分界点往左走的最大连续子序
  • 关于右边最大子序,是指从分界点往右走的最大连续子序

等我刷分治法的时候,再来更新了。

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/114451829
今日推荐