LeetCode 152 - 乘积最大子数组

题目描述

152. 乘积最大子数组

解法:DP(C++)

详细参考 官方题解

其实这道题用 DP 吼,最开始我是没有想到,我就想到了滑动窗。但是,滑动窗处理到后面其实和用滚动数组优化的 DP 其实一样了。所以,下面,我们就只说 DP 怎么解

我们有这样一个想法,如果前面的乘积都是负的,并且最后结尾的一个元素也是负的,那么我们就希望前面的乘积越小越好;如果前面的乘积是正的,并且最后结尾的一个元素也是正的,那么我们就希望前面的乘积越大越好

于是,我们定义 m m a x i mmax_i mmaxi 是以第 i i i 元素结尾的乘积, m m i n i mmin_i mmini 是以第 i i i 元素结尾的乘积,那么转移方程就是

m m a x i = m a x ( m m a x i − 1 ∗ n u m s [ i ] , m a x ( n u m s [ i ] , m m i n i − 1 ∗ n u m s [ i ] ) ) mmax_i = max(mmax_{i-1}*nums[i], max(nums[i], mmin_{i-1}*nums[i])) mmaxi=max(mmaxi1nums[i],max(nums[i],mmini1nums[i]))

m m i n i = m i n ( m m i n i − 1 ∗ n u m s [ i ] , m i n ( n u m s [ i ] , m m a x i − 1 ∗ n u m s [ i ] ) ) mmin_i = min(mmin_{i-1}*nums[i], min(nums[i], mmax_{i-1}*nums[i])) mmini=min(mmini1nums[i],min(nums[i],mmaxi1nums[i]))

注意吼,两次 m a x ( m i n ) max(min) max(min) 的顺序是不能交换的,因为不是三者比大小,而是对是否取 n u m s [ i ] nums[i] nums[i] 做出判断,为什么要对 n u m s [ i ] nums[i] nums[i] 做出判断呢?官方题解开头的例子已经说得很清楚了

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        if(nums.size()==0) return 0;
        if(nums.size()==1) return nums[0];
        int mmax = nums[0], mmin = nums[0], ans = nums[0];
        for(int i=1;i<nums.size();i++)
        {
            int mmax_tmp = mmax, mmin_tmp = mmin;
            mmax = max(mmax_tmp*nums[i], max(nums[i], mmin_tmp*nums[i]));
            mmin = min(mmin_tmp*nums[i], min(nums[i], mmax_tmp*nums[i]));
            ans = max(mmax, ans);
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值