最大连续子数组和 动态规划_LeetCode152. 乘积最大子数组

c6670cc9c56fa2ce049bc80e50dbb409.png

要求乘积最大的子数组(子数组一定都是连续的),可以暴力枚举子数组起点和终点,求和。但是肯定超时。

如果用动态规划,则只需要一遍扫描就可以得出结果。

可以用maxProduct[i]表示以i结尾的最大的子数组乘积。

如果所有nums[i]都是正数,则maxProduct[i]就是max(nums[i], maxProduct[i - 1] * nums[i]), 也就是当前数和以i - 1结尾的最大子数组乘积和当前数的乘积的较大值。

但是在这题里,nums[i]有可能是负数,众所周知负负得正,所以有可能前面某个子数组的乘积非常的“负”且当前的nums[i]也是一个负数, 以至于之前的那个负的子数组的积和nums[i]的乘积反而是最大的。

因此我们不仅需要一个maxProduct数组记录以当前位置i结尾的最大子数组的积,还需要一个minProduct数组记录以当前位置i结尾的最小子数组的积。

对于每一个maxProduct[i],它的值应该是nums[i], maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i]三者中最大的, 对于每一个minProduct[i],它的值是三者中最小的。

我们只需要一遍扫描更新所有的maxProduct和minProduct。

最终答案就是maxProduct数组中的最大值。

代码如下:

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int size = nums.size();
        vector<int> maxProduct(size), minProduct(size);
        maxProduct[0] = nums[0], minProduct[0] = nums[0];
        for(int i = 1; i < size; ++i) {
            maxProduct[i] = max(nums[i], max(maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i]));            //这一行和下一行对调位置也行,只要更新了maxProduct和minProduct就好
            minProduct[i] = min(nums[i], min(maxProduct[i - 1] * nums[i], minProduct[i - 1] * nums[i]));
        }
        return *max_element(maxProduct.begin(), maxProduct.end());
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值