Description
Given an integer array nums, find a that has the largest product, and return the product.
The test cases are generated so that the answer will fit in a 32-bit integer.
Example 1:
Input: nums = [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: nums = [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
Constraints:
1 <= nums.length <= 2 * 104-10 <= nums[i] <= 10- The product of any subarray of
numsis guaranteed to fit in a 32-bit integer.
Approach
- Use prefix and suffix product, the way it moves from both side it seems to ensure to cover all subarrays
- If we encounter a zero then set prefix and suffix as 1
class Solution {
public int maxProduct(int[] nums) {
int p = 1, s = 1;
int m = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
if (p == 0) p = 1;
if (s == 0) s = 1;
p *= nums[i];
s *= nums[nums.length - i - 1];
m = Math.max(m, Math.max(p,s));
}
return m;
}
}Primary Approach: Dynamic Programming (Tracking Min and Max Products) ( Time, Space)
Intuition
Unlike 53. Maximum Subarray, multiplying two negative numbers yields a positive number. Therefore, a very small negative product can suddenly become the largest positive product if multiplied by another negative number.
- At each element
nums[i], maintain two running values:currMax: The maximum product of a subarray ending at indexi.currMin: The minimum product of a subarray ending at indexi.
- When
nums[i]is negative, multiplying bycurrMaxyields a smaller number, while multiplying bycurrMinyields a larger number. Thus, swapcurrMaxandcurrMinbefore calculating updates. - Update values:
currMax = max(nums[i], currMax * nums[i])currMin = min(nums[i], currMin * nums[i])
- Update global
maxProductwithcurrMaxat each step.
class Solution {
public int maxProduct(int[] nums) {
int result = nums[0];
int currMax = nums[0];
int currMin = nums[0];
for (int i = 1; i < nums.length; i++) {
int num = nums[i];
// Multiplying by a negative flips max to min and min to max
if (num < 0) {
int temp = currMax;
currMax = currMin;
currMin = temp;
}
currMax = Math.max(num, currMax * num);
currMin = Math.min(num, currMin * num);
result = Math.max(result, currMax);
}
return result;
}
}
Complexity
- Time Complexity: — Single pass through array of length .
- Space Complexity: auxiliary space — Only uses extra variables (
currMax,currMin,result).
Alternative Approach: Prefix & Suffix Product Traversal ( Time, Space)
Intuition
Consider the properties of array products:
- If an array contains no zeros and an even number of negative values, the maximum product is the product of all elements.
- If an array contains an odd number of negative values, removing either the prefix ending at the first negative number or the suffix starting at the last negative number leaves an even count of negative numbers.
- If
0is encountered, it resets any product chain to1.
Thus, computing the prefix product (left to right) and suffix product (right to left) simultaneously guarantees covering the optimal subarray boundary.
class Solution {
public int maxProduct(int[] nums) {
int n = nums.length;
long prefix = 1;
long suffix = 1;
long maxProd = Long.MIN_VALUE;
for (int i = 0; i < n; i++) {
if (prefix == 0) prefix = 1;
if (suffix == 0) suffix = 1;
prefix *= nums[i];
suffix *= nums[n - 1 - i];
maxProd = Math.max(maxProd, Math.max(prefix, suffix));
}
return (int) maxProd;
}
}
Complexity
- Time Complexity: — Single loop running iterations to calculate prefix and suffix products.
- Space Complexity: auxiliary space.
Key Interview Discussion Points
- Why standard Kadane’s Algorithm fails: Basic Kadane’s algorithm assumes local subproblems are monotonic (larger values stay larger). With negative numbers, a negative product can flip into a maximum positive product on the next negative element.
- Handling Zeros: Any zero encountered forces local subarray product candidates to reset. Both DP and Two-Pointer (Prefix/Suffix) approaches handle
0by resetting running products to .
Easy Memory Rule
“Negative flips sign Track both
currMaxANDcurrMin(or compute Left-to-Right and Right-to-Left products)!”