Maximum Product Subarray in DSA Typescript - 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: number[]): number {
let maxProd = nums[0], minProd = nums[0], result = nums[0];
for (let i = 1; i < nums.length; i++) {
const 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 each element of the array once.
- How many times: The loop runs exactly 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 way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 loop steps |
| 100 | About 99 loop steps |
| 1000 | About 999 loop steps |
Pattern observation: The number of steps grows 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 in a straight line 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 operations are constant time and do not depend on the input size, so the overall time still grows linearly.
Understanding this linear time solution shows you can handle tricky problems efficiently, a skill that is valuable in many coding challenges and real projects.
"What if we used a nested loop to check every possible subarray product? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem statement
The problem asks for a contiguous part of the array where the product of all numbers is as large as possible.Step 2: Differentiate from similar problems
This is different from finding the largest sum or smallest product; it specifically focuses on the product of elements in a continuous segment.Final Answer:
The contiguous subarray with the largest product of its elements -> Option BQuick Check:
Maximum product subarray means largest product segment [OK]
- Confusing product with sum
- Ignoring that subarray must be contiguous
- Thinking about longest subarray instead of max product
Solution
Step 1: Check input parameter type
The input should be an array of numbers, so nums: number[] is correct.Step 2: Check return type
The function returns the maximum product value, which is a number, not an array or string.Final Answer:
function maxProduct(nums: number[]): number -> Option AQuick Check:
Input array, output number matches signature [OK]
- Using string type for input or output
- Returning array instead of number
- Incorrect parameter types
function maxProduct(nums: number[]): number {
let maxProd = nums[0];
let minProd = nums[0];
let 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([2, 3, -2, 4]));Solution
Step 1: Initialize variables and start loop
maxProd, minProd, and result start at 2. Loop from index 1 to 3.Step 2: Iterate and update maxProd, minProd, and result
At i=1 (3): maxProd = max(3, 2*3)=6, minProd = min(3, 2*3)=3, result=6.
At i=2 (-2): nums[i]<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.
At i=3 (4): maxProd = max(4, -2*4) = max(4, -8) = 4.
minProd = min(4, -12*4) = min(4, -48) = -48.
result = max(6, 4) = 6.Final Answer:
6 -> Option AQuick Check:
Max product subarray is [2,3] = 6 [OK]
- Not swapping max and min on negative number
- Only tracking max product, ignoring min product
- Confusing max product with sum
function maxProduct(nums: number[]): number {
let maxProd = 1;
let minProd = 1;
let result = Number.MIN_VALUE;
for (let num of nums) {
if (num < 0) {
let temp = maxProd;
maxProd = minProd;
minProd = temp;
}
maxProd = Math.max(num, maxProd * num);
minProd = Math.min(num, minProd * num);
result = Math.max(result, maxProd);
}
return result;
}Solution
Step 1: Understand Number.MIN_VALUE usage
Number.MIN_VALUE is the smallest positive number close to zero, not the most negative number.Step 2: Correct initialization for result
To track maximum product correctly, result should start at Number.NEGATIVE_INFINITY to handle negative products properly.Final Answer:
Using Number.MIN_VALUE instead of Number.NEGATIVE_INFINITY for result -> Option DQuick Check:
Use Number.NEGATIVE_INFINITY for max tracking [OK]
- Confusing Number.MIN_VALUE with negative infinity
- Not swapping max and min on negative number
- Wrong initial values for maxProd and minProd
[-1, -3, -10, 0, 60], what is the maximum product subarray and its product?Solution
Step 1: Analyze subarrays and their products
Check products of contiguous subarrays:
[-1] = -1
[-1, -3] = 3
[-1, -3, -10] = -30
[-3] = -3
[-3, -10] = 30
[-10] = -10
[0] = 0
[60] = 60Step 2: Identify maximum product
The largest product found is 60 from subarray [60].Final Answer:
Subarray: [60], Product: 60 -> Option CQuick Check:
Max product is 60 from single element [60] [OK]
- Assuming negative product is maximum
- Ignoring single element subarrays
- Confusing zero product with max product
Ready to prove it?
Pass the test and this pattern moves unknown
