LeetCode-152. 乘积最大子数组

LeetCode-152. 乘积最大子数组(中等)

题目地址:https://leetcode-cn.com/problems/maximum-product-subarray/

1. 题目描述及示例

      给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
      测试用例的答案是一个 32-位 整数。
      子数组 是数组的连续子序列。

示例一:

输入: nums = [2,3,-2,4]
输出: 6
解释:子数组 [2,3] 有最大乘积 6。

示例二:

输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

2. 题解和代码实现

      采用最大子序和的经验53.最大子数组和 ,我们可以进行定义 :

    max_results = max(max_results*nums[i]),nums[i])

但是如果遇到[-2,3,4,-5,6],会发现按照上式所得到的结果是{-2,3,12,-5,6} 那么最终的最大结果是12,显然不是我们想要的,也就是我们想要的结果:当前位置的最优解未必是由前一位置的最优解转移得到的
      所以,在这里可以进行分为正类的负类如果当前位置是一个正数,我们希望他的前一位置结尾的某个段的积是正数,并且希望它越大越好如果当前位置是一个负数, 我们希望他的前一位置结尾的某个段的积是负数,并且希望它越小越好。采用maxF来进行表示正类,minF来进行表示负类。即:

  1. 所以最大值,应该是 :
     max{maxF[i-1]*nums[i],minF[i-1]*nums[i],nums[i]}
  1. 所以最大值,应该是 :
     min{maxF[i-1]*nums[i],minF[i-1]*nums[i],nums[i]}

2.1 初始化

      在这里进行初始化:利用 max_result 来进行存储最终的最大值,用 maxFminF 分别来进行存储正类和负类。

    int max_result = nums[0],maxF = nums[0],minF = nums[0];

2.2 状态转移方程

      在这里的每一步更新需要用到前一步的结果,所以首先进行前一步结果的保存。

    int mx = maxF,mi = minF;
    maxF = max(mx*nums[i],max(mi*nums[i],nums[i]));
    minF = min(mi*nums[i],min(mx*nums[i],nums[i]));

代码实现(C++ 2022-4-8)

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        // 优化空间
        int max_result = nums[0],maxF = nums[0],minF = nums[0];
        // int max_result = maxF = minF = nums[0];
        for(int i=1;i<nums.size();i++){
            int mx = maxF,mi = minF;
            maxF = max(mx*nums[i],max(mi*nums[i],nums[i]));
            minF = min(mi*nums[i],min(mx*nums[i],nums[i]));
            max_result = max(max_result,maxF);
        }
        // vector <int> maxF(nums.size(),0), minF(nums.size(),0);
        // maxF[0] = minF[0] = nums[0];
        // int max_result = maxF[0];
        // for (int i = 1; i < nums.size(); ++i) {
        //     maxF[i] = max(maxF[i - 1] * nums[i], max(nums[i], minF[i - 1] * nums[i]));
        //     minF[i] = min(minF[i - 1] * nums[i], min(nums[i], maxF[i - 1] * nums[i]));
        //     max_result = max(maxF[i],max_result);
        // }
        return  max_result;
    }
};

3. 总结

       尽管利用动态规划求解,注意当前位置的最优解未必是由前一位置的最优解转移得到的 这一情况,要进行合理的分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zh-yi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值