0
点赞
收藏
分享

微信扫一扫

23. (★ 动态规划 没思路)剑指 Offer 42. 连续子数组的最大和

黄昏孤酒 2022-02-27 阅读 55

题目描述

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

思路:没有思路,能想到 联系最大利润的情况,但是还是无法下手!

想清楚了问题:① 每到一个节点,都会有含有该节点的子数组,求和!② 每次得到最大和,和前面的最大和对比,每次留下最大的!

关键难点,就是理解包含 i 的子数组和!还是不好理解,仍然需要想!

根据贡献值正负的思想 来动态规划!

动态规划总结

① 斐波那契数列和青蛙跳台阶是一个类型:很明确的 当前n处的值和前面 n-1和n-2有联系!有明确的三个值之间的关系,滑动窗口简单!简单的求 n 处的值

② 最大利润:每次到 i 处时,只用将当前值和之前的最小值相减得到新增加的最大利润,和之前的对比,留最大的!

③ 子数组最大和:和最大利润类似,比简单的当前值减去之前最小值难理解!但是有新的思路,就是往前找子数组:要么当前值就是最大;要么就是要包含上一个点在内;此时加上了前面的最大,就得到了当前最大!类推回去是一样的流程

②和③,相比① 多了一个比较的过程,并且每个点处的计算显得更加重要;不是简单的 紧挨的三个点之间的公式!

④ 动态规划要记住:首先动态变化的 要求的结果;其次,动态变化得到的结果不一定是直接需要的答案,如②和③,需要每次对比,记录

动态规划时间复杂度都是 O(N),空间复杂度可能是 O(1)和O(N)

代码:1)动态规划,时间复杂度 O(N)

class Solution {
    public int maxSubArray(int[] nums) {
        //这道题的关键:每次计算  包含当前节点的子数组的最大值!!! 不包含当前节点的不算
        //每个位置都有,然后比较
        //可以声明一个变量,在每次获得的时候都对比记录下最大值!
        int dp = nums[0];//每次计算的
        int maxSum = nums[0];//记录需要返回的
        for(int i = 1;i < nums.length;i++){
            //计算
            if(dp <= 0) dp = nums[i];
            else if(dp > 0) dp = nums[i] + dp;
            //记录最大
            maxSum = Math.max(dp,maxSum);
        }
        return maxSum;
    }
}
举报

相关推荐

0 条评论