LeetCode152-乘积最大子数组
题目
给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
解法
动态规划:
因为若整个数组都是正数或者有偶数个负数的话,从左到右乘起来是最大值
如果其中有奇数负数的话,从左到右乘起来是最小值
所以解这题的时候我们需要维护两个数组,当前的最大值,以及最小值,最小值可能为负数,但没准下一步乘以一个负数,当前的最大值就变成最小值,而最小值则变成最大值了。
注意: 还要考虑0,如果在某个位置是0的话,那么这个子数组就被截断了,最大值和最小值要重新统计。
class Solution {
public int maxProduct(int[] nums) {
int n = nums.length;
if(n == 0) return 0;
if(n == 1) return nums[0];
int[] maxDp = new int[n];
int[] minDp = new int[n];
maxDp[0] = nums[0];
minDp[0] = nums[0];
int max = maxDp[0];
for(int i = 1 ; i < n ; ++i){
int cur = nums[i];
maxDp[i] = Math.max(cur,Math.max(cur*maxDp[i-1],cur*minDp[i-1]));
minDp[i] = Math.min(cur,Math.min(cur*maxDp[i-1],cur*minDp[i-1]));
max = Math.max(max,maxDp[i]);
}
return max;
}
}
优化
class Solution {
public int maxProduct(int[] nums) {
int n = nums.length;
if(n == 0) return 0;
if(n == 1) return nums[0];
int maxDp = nums[0];
int minDp = nums[0];
int max = maxDp;
for(int i = 1 ; i < n ; ++i){
int cur = nums[i];
int maxPre = maxDp;
int minPre = minDp;
maxDp = Math.max(cur,Math.max(cur*maxPre,cur*minPre));
minDp = Math.min(cur,Math.min(cur*maxPre,cur*minPre));
max = Math.max(max,maxDp);
}
return max;
}
}s