给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-product-subarray
解题思路
用动态规划
当前数可能是正的负的或者是0
如果当前是正数,我们希望前面所累积的乘积是正的并且越大越好
如果当前是负数,我们希望前面所累积的乘积是负的并且越小越好
无论当前是正是负
maxDP = max(max * nums[i], min * nums[i], nums[i])
保存最大的连乘积
最大连乘积 = max(之前的最大连乘积 * 当前数, 之前的最小连乘积 * 当前数, 当前数)
minDP = min(max * nums[i], min * nums[i], nums[i])
保存最小的连乘积
最小连乘积 = min(之前的最大连乘积 * 当前数, 之前的最小连乘积 * 当前数, 当前数)
结果保留期间出现过的最大连乘积
代码
class Solution {
public int maxProduct(int[] nums) {
int maxDP = nums[0], minDP = nums[0], result = nums[0];
for (int i = 1; i < nums.length; i++) {
int max = maxDP, min = minDP;
maxDP = max(max * nums[i], min * nums[i], nums[i]);
minDP = min(max * nums[i], min * nums[i], nums[i]);
result = Math.max(result, maxDP);
}
return result;
}
private int max(int a, int b, int c) {
return Math.max(Math.max(a, b), c);
}
private int min(int a, int b, int c) {
return Math.min(Math.min(a, b), c);
}
}