Maximum Product Subarray in DSA C++ - 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.
int maxProduct(std::vector<int>& nums) {
int maxProd = nums[0], minProd = nums[0], result = nums[0];
for (int i = 1; i < nums.size(); i++) {
if (nums[i] < 0) std::swap(maxProd, minProd);
maxProd = std::max(nums[i], maxProd * nums[i]);
minProd = std::min(nums[i], minProd * nums[i]);
result = std::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: Exactly once for each element, so n times if the array has n elements.
As the array size grows, the number of steps grows directly in proportion.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: Doubling the input size roughly doubles the work done.
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 there are nested calculations inside the loop, the time complexity must be quadratic O(n²)."
[OK] Correct: The calculations inside the loop are constant time operations done once per element, so the loop still runs only n times, making the overall complexity linear.
Understanding this linear time solution shows you can handle tricky problems efficiently, a skill valued in real coding challenges and interviews.
"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 the highest possible.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
- Thinking about non-contiguous subarrays
Solution
Step 1: Understand initialization role
We start with 1 because multiplying by 1 doesn't change product; it acts as neutral.Step 2: Check each option
int maxProd = 1, minProd = 1; uses 1 for both maxProd and minProd, which is correct for product tracking.Final Answer:
int maxProd = 1, minProd = 1; -> Option DQuick Check:
Initialize maxProd and minProd to 1 [OK]
- Using 0 which resets product
- Using INT_MIN or INT_MAX incorrectly
- Not initializing min product
int arr[] = {2, 3, -2, 4};
int n = 4;
int maxProd = arr[0], minProd = arr[0], result = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] < 0) std::swap(maxProd, minProd);
maxProd = std::max(arr[i], maxProd * arr[i]);
minProd = std::min(arr[i], minProd * arr[i]);
result = std::max(result, maxProd);
}
std::cout << result << std::endl;Solution
Step 1: Trace the loop iterations
Start with maxProd=2, minProd=2, result=2. - i=1 (3): arr[i]=3 >0, no swap maxProd = max(3, 2*3)=6 minProd = min(3, 2*3)=3 result = max(2,6)=6 - i=2 (-2): arr[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 - i=3 (4): arr[i]=4 >0, no swap maxProd = max(4, -2*4)=max(4,-8)=4 minProd = min(4, -12*4)=min(4,-48)=-48 result = max(6,4)=6Step 2: Determine final result
The maximum product found is 6.Final Answer:
6 -> Option AQuick Check:
Maximum product subarray = 6 [OK]
- Not swapping max and min on negative
- Confusing max and min updates
- Ignoring initial values
int maxProduct(int arr[], int n) {
int maxProd = 1, minProd = 1, result = 1;
for (int i = 0; i < n; i++) {
if (arr[i] < 0) std::swap(maxProd, minProd);
maxProd = std::max(arr[i], maxProd * arr[i]);
minProd = std::min(arr[i], minProd * arr[i]);
result = std::max(result, maxProd);
}
return result;
}Solution
Step 1: Analyze loop start and initial values
Starting loop at i=0 uses maxProd=1 and minProd=1 before processing first element, which can cause wrong product calculations.Step 2: Correct approach for initialization and loop
Initialize maxProd, minProd, and result to arr[0] and start loop from i=1 to correctly track products.Final Answer:
Starting loop from i=0 causes incorrect initial values -> Option CQuick Check:
Loop should start at 1 with initial values from arr[0] [OK]
- Loop starting at 0 with default initial values
- Swapping max and min at wrong time
- Wrong initialization of result
int arr[] = {-1, -3, -10, 0, 60};, what is the maximum product of any contiguous subarray?Solution
Step 1: Analyze subarrays and their products
Check products of contiguous subarrays: - [-1] = -1 - [-1, -3] = 3 - [-1, -3, -10] = 30 - [-3, -10] = 30 - [-3, -10, 0] = 0 - [0, 60] = 0 - [60] = 60 - [-1, -3, -10, 0, 60] = 0 The maximum product is 30 from subarray [-1, -3, -10].Step 2: Check if any larger product exists
Although 60 is a single element, the product 30 from three negatives is smaller. The maximum product is 30, but 180 is possible if we consider [-3, -10, 0, 60] incorrectly. Actually, the maximum product is 60 from [60]. However, the product of [-1, -3, -10] is 30, not 180. The option 180 is incorrect as no contiguous subarray produces 180.Final Answer:
60 -> Option AQuick Check:
Max product subarray = 60 [OK]
- Ignoring zero breaks subarray
- Multiplying across zero incorrectly
- Not considering negative number pairs
Ready to prove it?
Pass the test and this pattern moves unknown
