Maximum Product Subarray in DSA Javascript - 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.
function maxProduct(nums) {
let maxProd = nums[0];
let minProd = nums[0];
let result = nums[0];
for (let i = 1; i < nums.length; i++) {
let tempMax = maxProd;
maxProd = Math.max(nums[i], maxProd * nums[i], minProd * nums[i]);
minProd = Math.min(nums[i], 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 the array once.
- How many times: The loop runs once for each element after the first, so (n - 1) times if n is the array length.
As the array size grows, the number of steps grows roughly the same amount.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 loop steps |
| 100 | About 99 loop steps |
| 1000 | About 999 loop steps |
Pattern observation: The steps increase directly with the input size, so doubling the input roughly doubles the work.
Time Complexity: O(n)
This means the time to find the maximum product grows linearly with the size of the input array.
[X] Wrong: "Because we check multiple products inside the loop, the time complexity is more than linear, maybe quadratic."
[OK] Correct: Inside the loop, the number of operations is fixed and does not depend on the input size, so the overall time still grows linearly.
Understanding this linear time solution shows you can handle problems that need careful tracking of multiple values while keeping efficiency.
"What if we used nested loops to check every possible subarray product? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem goal
The problem asks for the contiguous subarray (elements next to each other) that has the maximum product when multiplied together.Step 2: Differentiate from sum problems
This is different from maximum sum subarray problems because it focuses on multiplication, which can be affected by negative numbers and zeros.Final Answer:
The contiguous subarray with the largest product of its elements -> Option DQuick Check:
Maximum Product Subarray = largest product subarray [OK]
- Confusing product with sum
- Ignoring negative numbers impact
- Thinking about non-contiguous subarrays
Solution
Step 1: Understand variable roles
maxProd and minProd track the max and min products ending at current index; result stores the overall max product.Step 2: Correct initialization
Initializing all three to the first element of the array ensures correct comparison and handling of negative numbers.Final Answer:
let maxProd = nums[0], minProd = nums[0], result = nums[0]; -> Option CQuick Check:
Initialize with first element for correct tracking [OK]
- Initializing with zero causes wrong results if first element is negative
- Using arrays instead of numbers for tracking
- Using Infinity values incorrectly
const nums = [2, 3, -2, 4];
function maxProduct(nums) {
let maxProd = nums[0], minProd = nums[0], result = nums[0];
for (let i = 1; i < nums.length; i++) {
if (nums[i] < 0) [maxProd, minProd] = [minProd, maxProd];
maxProd = Math.max(nums[i], maxProd * nums[i]);
minProd = Math.min(nums[i], minProd * nums[i]);
result = Math.max(result, maxProd);
}
return result;
}
console.log(maxProduct(nums));Solution
Step 1: Trace the loop and variable updates
Start with maxProd=2, minProd=2, result=2.
i=1 (3): maxProd=max(3,2*3)=6, minProd=min(3,2*3)=3, result=max(2,6)=6.
i=2 (-2): nums[i]<0 so 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.
i=3 (4): maxProd=max(4,-2*4)=4, minProd=min(4,-12*4)=-48, result=max(6,4)=6.Step 2: Determine final result
The maximum product found is 6 from subarray [2,3].Final Answer:
6 -> Option BQuick Check:
Max product subarray = 6 [OK]
- Not swapping max and min on negative numbers
- Confusing max product with sum
- Incorrectly updating result
function maxProduct(nums) {
let maxProd = 0, minProd = 0, result = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] < 0) [maxProd, minProd] = [minProd, maxProd];
maxProd = Math.max(nums[i], maxProd * nums[i]);
minProd = Math.min(nums[i], minProd * nums[i]);
result = Math.max(result, maxProd);
}
return result;
}Solution
Step 1: Check variable initialization
Initializing maxProd, minProd, and result to 0 causes wrong results if nums[0] is negative or non-zero. They should start at nums[0].Step 2: Confirm loop start and swap logic
Loop starting at 0 is okay if initialization is correct. Swap on negative is needed to handle sign changes.Final Answer:
Initialize maxProd, minProd, and result with nums[0] instead of 0 -> Option AQuick Check:
Correct initialization fixes wrong product tracking [OK]
- Starting loop at 0 with zero initialization
- Removing swap logic on negative numbers
- Updating result with min instead of max
nums = [1, -2, -3, 0, 7, -8, -2], what is the maximum product of any contiguous subarray?Solution
Step 1: Trace subarrays and products
Check subarrays:
- [1] = 1
- [1,-2] = -2
- [1,-2,-3] = 6
- [-2,-3] = 6
- [7] = 7
- [7,-8] = -56
- [7,-8,-2] = 112 (max so far)
Zero resets product.
Other subarrays have smaller products.Step 2: Identify max product
The maximum product is 112 from subarray [7, -8, -2].Final Answer:
112 -> Option AQuick Check:
Max product subarray = 112 [OK]
- Ignoring zeros resetting product
- Not considering negative number pairs
- Only checking positive subarrays
Ready to prove it?
Pass the test and this pattern moves unknown
