Maximum Product Subarray in DSA Java - Time & Space Complexity
We want to understand how the time needed to find the maximum product of a subarray changes as the input array grows.
How does the number of steps grow when the array gets bigger?
Analyze the time complexity of the following code snippet.
public int maxProduct(int[] nums) {
int maxProd = nums[0];
int minProd = nums[0];
int result = nums[0];
for (int i = 1; i < nums.length; i++) {
int tempMax = maxProd;
maxProd = Math.max(nums[i], Math.max(maxProd * nums[i], minProd * nums[i]));
minProd = Math.min(nums[i], Math.min(tempMax * nums[i], minProd * nums[i]));
result = Math.max(result, maxProd);
}
return result;
}
This code finds the maximum product of any contiguous subarray in the input array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop that goes through each element of the array once.
- How many times: The loop runs exactly once for each element after the first, so (n - 1) times for an array of size n.
As the array size grows, the number of steps grows roughly the same amount, because we check each element once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 steps |
| 100 | About 99 steps |
| 1000 | About 999 steps |
Pattern observation: The steps increase linearly as the input size increases.
Time Complexity: O(n)
This means the time to find the maximum product grows in direct proportion to the size of the input array.
[X] Wrong: "Because we check products of subarrays, the time must be quadratic or worse."
[OK] Correct: The code cleverly keeps track of max and min products at each step, so it does not check all subarrays separately, avoiding extra loops.
Understanding this linear time approach shows you can solve tricky problems efficiently by tracking important values as you go, a skill highly valued in interviews.
"What if we used nested loops to check every possible subarray product? How would the time complexity change?"
Practice
Maximum Product Subarray problem ask you to find in an integer array?Solution
Step 1: Understand the problem statement
The problem asks for the contiguous subarray within an array that has the maximum product of its elements.Step 2: Differentiate from similar problems
This is different from maximum sum subarray; here we multiply elements, not add.Final Answer:
The contiguous subarray with the largest product of its elements -> Option BQuick Check:
Maximum Product Subarray = Largest product subarray [OK]
- Confusing product with sum
- Ignoring negative numbers impact
- Assuming non-contiguous subarrays
Solution
Step 1: Identify correct initial values for tracking products
We start maxProd and minProd at 1 because multiplying by 1 doesn't change the product. Result starts at smallest integer to update correctly.Step 2: Check each option's initialization
int maxProd = 1, minProd = 1; int result = Integer.MIN_VALUE; correctly initializes maxProd and minProd to 1 and result to Integer.MIN_VALUE for proper comparison.Final Answer:
int maxProd = 1, minProd = 1; int result = Integer.MIN_VALUE; -> Option DQuick Check:
Initialize maxProd and minProd to 1, result to min int [OK]
- Initializing max/min product to 0 causes wrong multiplication
- Setting result to 0 misses negative max products
- Using maxProd = Integer.MIN_VALUE breaks multiplication logic
int[] nums = {2, 3, -2, 4};?
int maxProd = 1, minProd = 1, result = Integer.MIN_VALUE;
for (int num : nums) {
if (num < 0) {
int temp = maxProd;
maxProd = minProd;
minProd = temp;
}
maxProd = Math.max(num, maxProd * num);
minProd = Math.min(num, minProd * num);
result = Math.max(result, maxProd);
}
System.out.println(result);Solution
Step 1: Trace the loop for each element
Start: maxProd=1, minProd=1, result=Integer.MIN_VALUE - num=2: maxProd=max(2,1*2)=2, minProd=min(2,1*2)=2, result=max(MIN_VALUE,2)=2 - num=3: maxProd=max(3,2*3)=6, minProd=min(3,2*3)=3, result=max(2,6)=6 - num=-2: num<0 swap maxProd and minProd: maxProd=3, minProd=6 maxProd=max(-2,3*(-2))=max(-2,-6)=-2 minProd=min(-2,6*(-2))=min(-2,-12)=-12 result=max(6,-2)=6 - num=4: maxProd=max(4,-2*4)=max(4,-8)=4 minProd=min(4,-12*4)=min(4,-48)=-48 result=max(6,4)=6Step 2: Final result after loop
The maximum product found is 6.Final Answer:
6 -> Option CQuick Check:
Max product subarray = 2*3 = 6 [OK]
- Not swapping max and min on negative number
- Confusing max and min updates
- Forgetting to update result each iteration
int maxProd = 1, minProd = 1, result = Integer.MIN_VALUE;
for (int num : nums) {
if (num <= 0) {
int temp = maxProd;
maxProd = minProd;
minProd = temp;
}
maxProd = Math.max(num, maxProd * num);
minProd = Math.min(num, minProd * num);
result = Math.max(result, maxProd);
}Solution
Step 1: Analyze the condition for swapping maxProd and minProd
The swap is needed only when the current number is negative because multiplying by a negative flips max and min.Step 2: Identify why <= 0 causes error
When num is zero, swapping maxProd and minProd is incorrect and breaks logic. So condition should be strictly < 0.Final Answer:
Change condition tonum < 0instead ofnum <= 0-> Option AQuick Check:
Swap only on negative numbers [OK]
- Swapping on zero causes wrong product calculations
- Not swapping at all misses negative impact
- Updating result outside loop misses intermediate max
int[] nums = {-1, -3, -10, 0, 60};, what is the maximum product of any contiguous subarray?Solution
Step 1: Consider subarrays and their products
Check subarrays: - [-1] = -1 - [-1, -3] = 3 - [-1, -3, -10] = -30 - [-3, -10] = 30 - [-3, -10, 0] = 0 - [0, 60] = 0*60=0 - [60] = 60 - [-1, -3, -10, 0, 60] = 0 - [-3, -10, 0, 60] = 0 - [-10, 0, 60] = 0 - [-1, -3, -10, 0] = 0Step 2: Identify maximum product subarray
Notice [-3, -10, 0, 60] includes zero, product zero. But [-1, -3, -10] product is -1 * -3 * -10 = -30 (negative). Check [-3, -10] = 30 (positive). Check [-1, -3] = 3. Check [-3, -10, 0, 60] zero product. Check [0, 60] = 0. Check [60] = 60. Check [-1, -3, -10, 0, 60] = 0. But what about [-1, -3, -10]? Actually, the product is -1 * -3 * -10 = -1 * 30 = -30 (negative). So max product is 60. But what about [-1, -3, -10, 0, 60]? Zero breaks subarray, so max product subarray is either before or after zero. So max product is 60.Step 3: Reconsider negative products with even count
Wait, the product of [-1, -3, -10] is -1 * -3 * -10 = -1 * 30 = -30 (negative). But what about [-1, -3, -10, 0, 60]? Zero breaks subarray. Check [-1, -3, -10] product is negative. Check [-3, -10] product is 30. Check [-1, -3] product is 3. Check [60] product is 60. So max product is 60. But what about [-1, -3, -10, 0, 60]? Zero breaks subarray. So max product is 60.Step 4: Final check with code logic
Using code logic: - Start maxProd=1, minProd=1, result=Integer.MIN_VALUE - num=-1: num<0 swap maxProd and minProd: maxProd=1, minProd=1 maxProd=max(-1,1*-1)=-1 minProd=min(-1,1*-1)=-1 result=max(MIN_VALUE,-1)=-1 - num=-3: num<0 swap maxProd and minProd: maxProd=-1, minProd=-1 maxProd=max(-3,-1*-3)=max(-3,3)=3 minProd=min(-3,-1*-3)=min(-3,3)=-3 result=max(-1,3)=3 - num=-10: num<0 swap maxProd and minProd: maxProd=-3, minProd=3 maxProd=max(-10,-3*-10)=max(-10,30)=30 minProd=min(-10,3*-10)=min(-10,-30)=-30 result=max(3,30)=30 - num=0: num not <0 no swap maxProd=max(0,30*0)=max(0,0)=0 minProd=min(0,-30*0)=min(0,0)=0 result=max(30,0)=30 - num=60: num not <0 no swap maxProd=max(60,0*60)=max(60,0)=60 minProd=min(60,0*60)=min(60,0)=0 result=max(30,60)=60 Final result is 60.Final Answer:
60 -> Option AQuick Check:
Maximum product subarray = 60 [OK]
- Assuming product of all negatives is always max
- Ignoring zero breaks subarray
- Not updating max/min product correctly after zero
Ready to prove it?
Pass the test and this pattern moves unknown
