Description
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
Solution
DP, time O(n), space O(1)
This is very similar to the " max cumulative sum subarray" problem. here you keep 2 values: the max cumulative product UP TO current element starting from SOMEWHERE in the past, and the minimum cumuliative product UP TO current element . it would be easier to see the DP structure if we store these 2 values for each index, like maxProduct[i],minProduct[i] .
At each new element, u could either add the new element to the existing product, or start fresh the product from current index (wipe out previous results)
, hence the 2 Math.max() lines.
If we see a negative number, the “candidate” for max should instead become the previous min product, because a bigger number multiplied by negative becomes smaller, hence the swap().
class Solution {
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int max = nums[0];
// imax/imin stores the max/min product of
// subarray that ends with the current number A[i]
for (int i = 1, imax = nums[0], imin = nums[0]; i < nums.length; ++i) {
if (nums[i] < 0) {
int tmp = imax;
imax = imin;
imin = tmp;
}
// max/min product for the current number is
// either the current number itself
// or the max/min by the previous number times the current one
imax = Math.max(nums[i], nums[i] * imax);
imin = Math.min(nums[i], nums[i] * imin);
max = Math.max(max, imax);
}
return max;
}
}
也可以這樣泥从,注意需要用tmp保存中間值:
class Solution {
public int maxProduct(int[] nums) {
int maxProduct = Integer.MIN_VALUE;
for (int i = 0, imin = 1, imax = 1; i < nums.length; ++i) {
int tmp = imax;
imax = Math.max(nums[i], Math.max(imax * nums[i], imin * nums[i]));
imin = Math.min(nums[i], Math.min(tmp * nums[i], imin * nums[i]));
maxProduct = Math.max(maxProduct, Math.max(imax, imin));
}
return maxProduct;
}
}