leetcode:152. 乘积最大子数组

题目来源

题目描述

在这里插入图片描述

题目解析

  • 对于子数组问题,其dp一般定义为:必须以nums[i]结尾的子数组…,然后对于每一个dp[i]有两种选择:
    • 仅仅选择nums[i]
    • 以nums[i]为基地,向前扩展
  • 这里特殊的是:
    • 两个负数相乘可能会变得很大,负数*正数可能会变得很小。
    • 所以我们需要同时维护两个值-----最大值、最小值
class Solution {
    struct info{
        int max;
        int min;  // 两个负数相乘可能变得很大
        info(){
            max = INT32_MIN;
            min = INT32_MAX;
        }
    };
public:

    int maxProduct(vector<int>& nums) {
        int N = nums.size();
        if(N == 0){
            return 0;
        }
        //该子数组中至少包含一个数字
        if(N == 1){
            return nums[0];
        }


        std::vector<info> dp(N);          //必须以num[i]结尾的最大乘积子数组
        dp[0].min = nums[0];
        dp[0].max = nums[0];
        int ans = nums[0];
        for (int i = 1; i < N; ++i) {
            int p1 = nums[i];
            int p2 = nums[i] * dp[i - 1].min;  // 两个负数相乘可能变得很大
            int p3 = nums[i] * dp[i - 1].max;       // 测试用例的答案是一个 32-位 整数。 不会溢出
            dp[i].min = std::min(p1, std::min(p2, p3));
            dp[i].max = std::max(p1, std::max(p2, p3));
            ans = std::max(ans, dp[i].max);
        }
        return ans;
    }
};

上面,因为dp[i]仅仅依赖dp[i-1],所以:

class Solution {
public:

    int maxProduct(vector<int>& nums) {
        int N = nums.size();
        if(N == 0){
            return 0;
        }

        int pMin  = nums[0];
        int pMax = nums[0];
        int ans = nums[0];
        for (int i = 1; i < N; ++i) {
            int cMin = std::min(nums[i], std::min(nums[i] * pMin, nums[i] * pMax));
            int cMax = std::max(nums[i], std::max(nums[i] * pMin, nums[i] * pMax));
            ans = std::max(ans, cMax);
            pMin = cMin;
            pMax = cMax;
        }
        return ans;
    }
};

类似题目

题目思路
leetcode:53. [无序整数数组]子数组最大累加和是多少maximum-subarray动态规划、线段和、贪心
leetcode:152. [无序整数数组]子数组最大乘积是多少Maximum Product Subarray 动态规划(最小值 * 最小值可能变得很大)
leetcode:238. 除自身以外数组的乘积 Product of Array Except Self前缀和
leetcode:713. [无序正数数组]乘积 < K 的子数组个数subarray-product-less-than-k 滑动窗口
leetcode:198. 打家劫舍 House Robber动态规划
leetcode:628. [无序整数数组]三个数的最大乘积 Maximum Product of Three Numbers排序,然后利用数学性质
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值