LeetCode 之 乘积最大子数组

在这里插入图片描述
题目要求找出数组 nums 中乘积最大的连续子数组,最直接的办法是遍历整个数组,穷举以数组元素 nums[i] 为开头的所有连续子数组,通过比较所有连续子数组的乘积,找到最大值,并返回。

可是穷举所有子数组的乘积的过程中,存在很多重复计算。因此可以考虑使用动态规划的思想来优化算法。

知识点: 动态规划及其空间优化

1. 暴力遍历

这种方法通过穷举所有可能的结果,得到最大值。因此要对数组进行两次遍历,并假定数组首元素为乘积最大值 max 。
第一次遍历确定乘积子数组的开头元素 nums[i]
第二次遍历确定子数组的组成长度,子数组范围从开头元素 nums[i] 到 数组结尾 nums[nums.size() - 1] ,使用变量 multi 存储当前数组的乘积,并与最大值 max 比较。

class Solution {
   
public:
    int maxProduct(vector<int>& nums) {
   
        
        int max = nums[0];
        for(int i = 0; i < nums.size(); i++)
        {
   
            int multi = 1;
            for(int j = i; j < nums.size(); j++)
            {
   
                multi = multi * nums[j];
                max = max < multi ? multi : max;
            }
            
        }
        return max;
    }
};

2. 动态规划

“动态规划问题一定会具备「最优子结构」,才能通过子问题的最值得到原问题的最值。”
那么本题的最优子结构是什么呢?什么时候子数组的乘积为最大?

2.1 定义子问题

本题的子问题是找到乘积最大的所有元素吗?
不是,因为题目要求的是数组,乘积最大的若干元素可能并不相邻,所以无法构成数组。
本题的子问题应该为以 nums[i] 为结尾的乘积最大子数组。

2.2 状态转移方程

动态规划的核心就是写出状态转移方程,并给出基础条件。
下面我们尝试根据题目要求写出状态转移方程。

什么时候以 nums[i] 为结尾的子数组的乘积为最大?
一个正数乘一个正数还是一个正数,一个正数乘一个负数就是一个负数,两个负数相乘是正数。我们无法确定 nums[i] 是正数、负数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值