152. 乘积最大子数组
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
解题
设dp[i]为以i为终点的最大子数组乘积;
若给定数字>=0,则最大乘积为max(dp[i-1]*nums[i],nums[i]);
但给定数字存在负数,当遇到负数,最大值变为最小值,最小值变为最大值;
dp[i][0]存放以i为终点的最小值;
dp[i][1]存放以i为终点的最大值;
if(nums[i]>=0){
dp[i][0]=min(dp[i-1][0]*nums[i],nums[i]);
dp[i][1]=max(dp[i-1][1]*nums[i],nums[i]);
}
if(nums[i]<0){
dp[i][0]=min(dp[i-1][1]*nums[i],nums[i]);
dp[i][1]=max(dp[i-1][0]*nums[i],nums[i]);
}
遇到正数,dp由最小值推最小值,最大值推最大值;
遇到负数,dp由最大值推最小值,最小值推最大值;
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n=nums.size();
dp.resize(n,vector<int>(2,0));
//0存放最大值
//1存放最小值
res=nums[0];
dp[0][0]=nums[0];
dp[0][1]=nums[0];
for(int i=1;i<n;i++)
{
if(nums[i]>=0){
dp[i][0]=min(dp[i-1][0]*nums[i],nums[i]);
dp[i][1]=max(dp[i-1][1]*nums[i],nums[i]);
}
if(nums[i]<0){
dp[i][0]=min(dp[i-1][1]*nums[i],nums[i]);
dp[i][1]=max(dp[i-1][0]*nums[i],nums[i]);
}
}
for(int i=0;i<n;i++)
if(res<dp[i][1]) res=dp[i][1];
return res;
}
private:
int res;
vector<vector<int>> dp;
};

本文详细解析了寻找整数数组中乘积最大连续子数组的问题,通过动态规划方法,探讨了如何处理正数和负数情况下的子数组乘积变化,提供了完整的算法实现。

354

被折叠的 条评论
为什么被折叠?



