【每日刷题】Day119

【每日刷题】Day119

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

1. 918. 环形子数组的最大和 - 力扣(LeetCode)

2. 152. 乘积最大子数组 - 力扣(LeetCode)

3. 1567. 乘积为正数的最长子数组长度 - 力扣(LeetCode)

1. 918. 环形子数组的最大和 - 力扣(LeetCode)

//思路:子数组动态规划问题。

//本题核心思路与 Day 118 中 "最大子数组和" 思路一样。具体过程看图解:

class Solution {

public:

    const int INF = 0x3f3f3f3f;

    int maxSubarraySumCircular(vector<int>& nums)

    {

        int n = nums.size(),tmp1 = -INF,tmp2 = INF,sum = nums[0];

        vector<int> dp(n);

        dp[0] = nums[0];

        auto dp1 = dp;

        for(int i = 1;i<n;i++)

        {

            dp[i] = max(nums[i],nums[i]+dp[i-1]);//中间的最大子数组和

            dp1[i] = min(nums[i],nums[i]+dp1[i-1]);//中间的最小子数组和

            sum+=nums[i];//整个数组的和

        }

        for(int i = 0;i<n;i++)

        {

            tmp1 = tmp1>dp[i]?tmp1:dp[i];

            tmp2 = tmp2<dp1[i]?tmp2:dp1[i];

        }

        if(tmp2==sum) return tmp1;//[-3,-2,-3]特殊情况,最小子数组和就是整个数组

        return max(tmp1,sum-tmp2);

    }

};

2. 152. 乘积最大子数组 - 力扣(LeetCode)

//思路:子数组动态规划问题。

//本题思路与我们的 Day 118 中的 "最大子数组和" 问题十分相似,但是状态数组和方程差别很大:

class Solution {

public:

    const int INF = 0x3f3f3f3f;

    int maxProduct(vector<int>& nums)

    {

        int n = nums.size(),ans = -INF;

        vector<int> f(n);

        f[0] = nums[0];

        auto g = f;

        for(int i = 1;i<n;i++)

        {

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

            g[i] = min(nums[i],nums[i]*g[i-1]);

            if(nums[i]<0)

            {

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

                g[i] = min(nums[i],nums[i]*f[i-1]);

            }

        }

//最后的结果只可能出现在 f[i] 中

        for(int i = 0;i<n;i++) ans = ans>f[i]?ans:f[i];

        return ans;

    }

};

3. 1567. 乘积为正数的最长子数组长度 - 力扣(LeetCode)

//思路:子数组动态规划问题。

class Solution {

public:

    const int INF = 0x3f3f3f3f;

    int getMaxLen(vector<int>& nums)

    {

        int n = nums.size(),ans = -INF;

        vector<int> f(n+1),g(n+1);

        for(int i = 1;i<=n;i++)

        {

            if(nums[i-1]>0)

            {

                f[i] = f[i-1]+1;

                g[i] = g[i-1]==0?0:g[i-1]+1;

            }

            else if(nums[i-1]<0)

            {

                f[i] = g[i-1]==0?0:g[i-1]+1;

                g[i] = f[i-1]+1;

            }

//写入的同时更新结果,结果只可能出现在 f[i] 中

            ans = max(ans,f[i]);

        }

        return ans;

    }

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值