动态规划子数组(C++)


前言

在本文章中,我们将要详细介绍一下Leetcode(面试题 08.01.)三步问题相关的内容

918. 环形子数组的最大和

题目讲解

918. 环形子数组的最大和

算法原理

1.状态表示

我们想想结果可能出现的情况!!!
1.环形子数组的最大和区间就在中间位置
2.环形子数组的最大和区间左边一段,右边一段。
这就可以每个位置都可以是起始位置。
我们计算起来比较麻烦。我们可以用正难则反
我们知道整个数组的总和是多少,那么我们求出子数组的最小值。
用总和减去这个最小值就是我们所要的结果。

f[i]:到达i位置,此时环形子数组的最大和
g[i]:到达i位置,此时环形子数组的最小和

2.状态转移方程

f[i ]=max(f[i-1]+nums[i],nums[i]);
g[i]=max(g[i-1]+nums[i],nums[i]);

3.初始化

f[0]=g[0]=nums[0];

4.填表顺序

从左到右,两个表一起填写

5.返回值是什么

我们返回的是环形子数组的最大和。
最大和可能出现在上面两种情况中,我们需要再进行比大小。
每一个位置都可以是最大值,我们可以边填表一边记录极值。

我们还可能遇到特殊情况,
比如:nums =[-3,-2,-3]
f表max=-2;
我们按照上面求得sum=-8,最小值也是-8。二者相见就是0。
二者比大小返回的是0,但是0是错误的。
我们需要特殊判断

代码实现

class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) 
    {
        int sum=0;
        for(auto&e:nums)
        {
            sum+=e;
        }
        int n=nums.size();
        //建表
        vector<int>f(n,0);
        vector<int>g(n,0);
        //初始化
        f[0]=g[0]=nums[0];
        //统计最大值,最小值
        int fmax=nums[0];
        int gmin=nums[0];
        //填表
        for(int i=1;i<n;i++)
        {
            f[i]=max(f[i-1]+nums[i],nums[i]);
            g[i]=min(g[i-1]+nums[i],nums[i]);
            fmax=max(fmax,f[i]);
            gmin=min(gmin,g[i]);
        }
        //都是负数特殊处理
        if(sum==gmin) return fmax;
        return max(sum-gmin,fmax);

    }
};

总结

以上就是我们对Leetcode详细介绍,希望对大家的学习有所帮助,仅供参考 如有错误请大佬指点我会尽快去改正 欢迎大家来评论~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lim 鹏哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值