vlambda博客
学习文章列表

235.LeetCode | 152. 乘积最大子数组

每天一个开发小知识


01


题目

给你一个整数数组 nums


请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)


并返回该子数组所对应的乘积


示例 1:

输入: [2,3,-2,4]

输出: 6

解释: 子数组 [2,3] 有最大乘积 6


示例 2:

输入: [-2,0,-1]

输出: 0

解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。


02

思路

按照 动态规划 的解法是这样的

1.定义 dp


dp[i]:表示以第 i 个元素结尾的最大乘积

2.找到状态转移方程

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

3.确定目标 dp

max(dp[i])

4.初始化部分 dp

dp[0] = nums[0]

但是

运行结果错误

原因是数组中存在负数

使得状态转移方程不成立

在记录以第 i 个元素结尾的最大乘积时

还需记录以第 i 个元素结尾的 最小乘积

以防 nums[i] 为负数时

不会漏负负得正的情况

03

解法:动态规划

时间复杂度 O(n),空间复杂度 O(1)

class Solution { public: int maxProduct(vector<int>& nums) { int ret = nums[0]; int dp_max = nums[0]; int dp_min = nums[0];
for (int i = 1; i < nums.size(); ++i) { int dp_max_tmp = dp_max; int dp_min_tmp = dp_min;
dp_max = max(dp_max_tmp * nums[i], max(dp_min_tmp * nums[i], nums[i])); dp_min = min(dp_max_tmp * nums[i], min(dp_min_tmp * nums[i], nums[i]));
ret = max(ret, dp_max); }
return ret; }};

每天一个开发小知识,今天你学废了吗?