【动态规划】子数组系列一(数组中连续的一段)

在这里插入图片描述

点赞👍👍收藏🌟🌟关注💖💖
你的支持是对我最大的鼓励,我们一起努力吧!😃😃

1.最大子数组和

题目链接: 53. 最大子数组和

题目分析:

在这里插入图片描述

子数组 是数组中的一个连续部分。子数组最少包含一个元素也就是说本身也是子数组!

在这里插入图片描述

算法原理:

1.状态表示

像这种研究的是子数组这样的模型,状态表示 依旧可以用 经验 + 题目要求

以 i 位置为结尾,巴拉巴拉。

以 i 位置为结尾,我们要的是最大子数组和,是不是先把以 i 位置为结尾的所有子数组拿到。单独 i 元素 是一个子数组,还有前面以 i 元素 为结尾的所有子数组,我要的是一个最大和。

dp[i] 表示:以 i 位置元素为结尾的所有子数组中的最大和。

在这里插入图片描述

2.状态转移方程

找出所有子数组最大和就可以了,所有子数组可以划分两大类。第一类就是单独自己构成子数组,第二类就是它自己与前面元素的结合构成子数组。所以可以根据长度来划分,长度为1 单独自己构成子数组,子数组最大和 nums[i],长度大于1,nums[i]一定是要的,然后在找到以 i - 1 位置元素为结尾的所有子数组中的最大和,两个相加就可以了,而dp[i - 1] 就是以 i - 1 位置元素为结尾的所有子数组中的最大和,因此 dp[i + 1] + nums[i],我要求的是 i 位置元素为结尾的所有子数组中的最大和。因此两种情况取最大就好了

在这里插入图片描述

3.初始化

多申请一个节点

  1. 里面的值要保证后面填表的正确
  2. 下标映射关系

先考虑如果不多加一个节点第一个位置应该填多少呢?是不是填自己本身啊,为了不让多加的节点影响后面的填表正确,因此可以给 0。注意下标映射关系,我们躲开了一个空间相当于整体往右移动一位,如果要回原数组下标要 -1

在这里插入图片描述

4.填表顺序

从左往右

5.返回值

注意这里可不是返回最后一个位置的值,因为最大子数组可能在这个数组中任何一个地方。所以返回的是dp中最大值

class Solution {
   
public:
    int maxSubArray(vector<int>& nums) {
   
        // 1.创建 dp 表
        // 2.初始化
        // 3.填表
        // 4.返回值

        int n = nums.size();
        vector<int> dp(n + 1);
        for(int i = 1; i <= n; ++i)
        {
   
            dp[i] = max(nums[i - 1], dp[i - 1] + nums[i - 1]);
        }

        int ret = INT_MIN;
        for(int i = 1; i <= n; ++i)
            ret = max(ret,dp[i]);
        return ret;

    }
};

2.环形子数组的最大和

题目链接:

评论 124
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值