package com.freetymekiyan.algorithms.level.medium;
/**
* Find the contiguous subarray within an array (containing at least one number) which has the largest product.
* <p>
* For example, given the array [2,3,-2,4],
* the contiguous subarray [2,3] has the largest product = 6.
* <p>
* Company Tags: LinkedIn
* Tags: Array, Dynamic Programming
* Similar Problems: (M) Maximum Subarray, (E) House Robber, (M) Product of Array Except Self
*/
public class MaxProductSubArray {
/**
* DP. Bottom-up.
* We need to track both maximum product and minimum product.
* In case a minimum product multiply by a negative number and become maximum.
* f(k): Largest product subarray, from index 0 up to k.
* g(k): Smallest product subarray, from index 0 up to k.
* Similar to max sum subarray, the max product candidates are:
* 1. Build on previous subarray max product: f(k-1) * A[k]
* 2. Build on previous subarray min product: g(k-1) * A[k]
* 3. Start from right here: A[k]
* Recurrence Relation:
* f(k) = max( f(k-1) * A[k], A[k], g(k-1) * A[k] )
* g(k) = min( g(k-1) * A[k], A[k], f(k-1) * A[k] )
* Base:
* Initialize max, min and final result as the first number.
*/
public int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int max = nums[0], min = nums[0], res = nums[0];
for (int i = 1; i < nums.length; i++) {
int preMax = max, preMin = min; // IMPORTANT: max and min need tp be stored.
max = Math.max(Math.max(nums[i], preMax * nums[i]), preMin * nums[i]);
min = Math.min(Math.min(nums[i], preMax * nums[i]), preMin * nums[i]);
res = Math.max(max, res);
}
return res;
}
}