问题描述
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
问题分析
状态定义:
dp[0]
:当前数结尾的子数组最大值dp[1]
:当前数结尾的子数组的最小值
状态转移:
- 若当前数 x 为正数,则以 x 结尾的子数组的最大值为
max(x, x * 上一状态的最大值)
;最小值为min(x, x * 上一状态的最小值)
。 - 若当前数 x 为负数数,则以 x 结尾的子数组的最大值为
max(x, x * 上一状态的最小值)
;最大值为min(x, x * 上一状态的最大值)
。
在状态更新过程中,同时更新子数组乘积的最大值。当所有元素都已遍历完成时,则得到全局的最大值。
程序代码
class Solution {
public:
int maxProduct(vector<int>& nums) {
int res = nums[0];
int n = nums.size();
vector<int> dp(2, 0);
dp[0] = dp[1] = nums[0];
for(int i = 1; i < n; i++) {
int maxRes = dp[0], minRes = dp[1];
if(nums[i] < 0) {
dp[0] = max(nums[i], minRes * nums[i]);
dp[1] = min(nums[i], maxRes * nums[i]);
}
else {
dp[0] = max(nums[i], maxRes * nums[i]);
dp[1] = min(nums[i], minRes * nums[i]);
}
res = max(res, dp[0]);
}
return res;
}
};