动态规划-152.乘积最大子数组-力扣(LeetCode)

一、题目解析

根据示例nums数组中存在负数,下面分析时需注意

二、算法原理

1、状态表示

此时f[i]表示:以i位置为结尾的所有子数组中的最大乘积,但是由于nums中存在负数,所以还需要g[i]表示:以i位置为结尾的所有子数组中的最小乘积

2、状态转移方程

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

g[i]的分析过程差不多这里直接给出

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

3、初始化

由于要使用f[i-1]和g[i-1]所以可以选择直接初始化f[0]和g[0],也可以使用虚拟节点,即开辟空间时多开辟一个,用于初始化计算,且为了计算结果不影响后面填表,所以初始化为1,尤为注意我们初始化加了一格,下标的映射关系改变。

4、填表顺序

为了保证所需值已被计算,从左往右,两个表一起填。

5、返回值

根据题目要求我们只需要返回f表中的最大值即可

代码能力是需要实操的,坚持下来,152. 乘积最大子数组 - 力扣(LeetCode)

三、代码示例

cpp 复制代码
class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int n = nums.size();
        vector<int> f(n+1,1),g(n+1,1);
        for(int i = 1;i<=n;i++)
        {
            f[i]=max(nums[i-1],max(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
            g[i]=min(nums[i-1],min(f[i-1]*nums[i-1],g[i-1]*nums[i-1]));
        }
        int f_max = f[1];
        for(int i = 2;i<=n;i++)
        {
            if(f[i]>f_max) f_max = f[i];
        }
        return f_max;
    }
};

看到最后,如果对您有所帮助,还请点赞、收藏和关注,点点关注不迷路,我们下期再见!

相关推荐
天选之女wow36 分钟前
【代码随想录算法训练营——Day59】图论——47.参加科学大会、94.城市间货物运输I
算法·图论
CoovallyAIHub44 分钟前
1.2MB超轻量模型实现草莓苗精准分级检测与定位,准确率超96%
深度学习·算法·计算机视觉
CoovallyAIHub1 小时前
终结AI偏见!Sony AI发布Nature论文与FHIBE数据集,重塑公平性评估基准
深度学习·算法·计算机视觉
7澄11 小时前
深入解析 LeetCode 1572:矩阵对角线元素的和 —— 从问题本质到高效实现
java·算法·leetcode·矩阵·intellij-idea
ALex_zry1 小时前
c20 字符串处理优化可选方案
算法
阳光明媚sunny1 小时前
分糖果算法题
java·算法
卡提西亚1 小时前
一本通网站1125题:矩阵乘法
c++·算法·矩阵·编程题·一本通
程序员东岸1 小时前
数据结构精讲:从栈的定义到链式实现,再到LeetCode实战
c语言·数据结构·leetcode
laocooon5238578862 小时前
大数的阶乘 C语言
java·数据结构·算法
Boop_wu2 小时前
[Java EE] 多线程 -- 初阶(1)
java·jvm·算法