最大子序和--动态规划入门

先说题目

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
题目链接:https://leetcode-cn.com/problems/maximum-subarray

再看一下官方题解

lass Solution {
   public static int maxSubArray(int[] nums) {
       
     
        int res = nums[0];
        int sum = 0;
        for (int num : nums) {
            if (sum > 0)
                sum += num;
            else
                sum = num;
            res = Math.max(res, sum);
        }
        return res;
    }
 }

第一次看我是懵了但是 但是啊 我发现了一个非常好理解的帖子
可以直接拉到最下看原文


假设有这样一个数组: [a, b , c, d , e]

之前我们遍历他的子串或者子数组都是以开头遍历的
如 [a],[a, b],[ a, b, c] … 再从以 b 为开头的子序列开始遍历 [b] [b, c]。

但是到了动态规划 思路就不一样了

是以子序列的结束节点为基准
如: 以 b 为结束点的所有子序列: [a , b] [b]
以 c 为结束点的所有子序列: [a, b, c] [b, c] [ c ]。
这个题就是这个思路

思路说完了上代码

function  maxSubArray2  ( nums ) {
    if (!nums.length) {
        return;
    };
    // 在每一个扫描点计算以该点数值为结束点的子数列的最大和(正数和)。
    let max_ending_here = nums[0];//记录当前最大
    let max_so_far = nums[0];//记录全局最大

    for (let i = 1; i < nums.length; i ++ ) {
        **// 以每个位置为终点的最大子数列 都是基于其前一位置的最大子数列计算得出,**

        max_ending_here = Math.max ( nums[i], max_ending_here + nums[i]);
       //判断是当前值大还是当前的最大子数列加当前值大
        max_so_far = Math.max ( max_so_far, max_ending_here);
        //更新全局最大
    };

    return max_so_far;
};

代码优化

class maxSubArray = function(nums) {
    let ans = nums[0];
    let sum = 0;
    for(let num of nums) {
        // if(sum > 0) { 可以写成这样
        if(sum + num > num ){
            sum = sum + num;
        } else {
            sum = num;
        }
        ans = Math.max(ans, sum);
    }
    return ans;
}

第二块代码和 第一块代码 思路实现是完全一样的,对于这个 if (sum > 0 )
是 if(sum + num > num )两边约去num得来

思路原作者:lao-hu-8
链接:https://leetcode-cn.com/problems/maximum-subarray/solution/xiang-xi-jie-du-dong-tai-gui-hua-de-shi-xian-yi-li/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值