Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array
the contiguous subarray
Understand the problem:[2,3,-2,4]
,the contiguous subarray
[2,3]
has the largest product = 6
.The problem is very similar to the maximum subarray, which calculates the maximum addition of a subarray. Unlike the in the maximum subarray problem the local optimal can lead to the global optimal, the maximum product subarray cannot. e.g. -2 3 -4, where at -4 the local max is -4, however the global should be -2 * 3 * -4.
The solution is to maintain to dp arrays, one maintains the local min and the other maintain the local max. Therefore, we define the DP arrays as
dpMin[i], the minimum subarray INCLUDING nums[i]
dpMax[i], the maximum subarray INCLUDING nums[i]
dpMin[i] = Min(dpMin[i - 1] * A[i], dpMax[i - 1] * A[i], A[i]);
dpMax[i] = Max(dpMax[i - 1] * A[i], dp[Min[i - 1] * A[i], A[i]);
The final state is to check max(result, dpMax[i]).
Code (Java):
public class Solution { public int maxProduct(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int len = nums.length; int[] dpMin = new int[len]; int[] dpMax = new int[len]; dpMin[0] = nums[0]; dpMax[0] = nums[0]; for (int i = 1; i < len; i++) { dpMin[i] = Math.min(Math.min(dpMin[i - 1] * nums[i], dpMax[i - 1] * nums[i]), nums[i]); dpMax[i] = Math.max(Math.max(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i]), nums[i]); } int max = Integer.MIN_VALUE; for (int i = 0; i < len; i++) { max = Math.max(max, dpMax[i]); } return max; } }
A constant space solution:
Note that dp[i] only relies on dp[i - 1], so we could just use two variables to solve the problem.
Code (Java):
public class Solution { public int maxProduct(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int len = nums.length; int min = nums[0]; int max = nums[0]; int result = nums[0]; for (int i = 1; i < len; i++) { int curMin = Math.min(Math.min(min * nums[i], max * nums[i]), nums[i]); int curMax = Math.max(Math.max(max * nums[i], min * nums[i]), nums[i]); min = curMin; max = curMax; result = Math.max(result, max); } return result; } }
Follow-up:
How about the maximum product subsequence? For example, 2 -3 4, the result is 2 * 4 = 8
The solution would be very similar to the maximum product subarray. The only difference is max and min do not necessary include the nums[i]. Therefore,
min = Min(min, min * nums[i], max * nums[i], nums[i]);
max = Max(max, max * nums[i], min * nums[i], nums[i]);
result = Max(result, max);
No comments:
Post a Comment