Bird
Raised Fist0
DSA Cprogramming~15 mins

Maximum Product Subarray in DSA C - Deep Dive

Choose your learning style10 modes available
Overview - Maximum Product Subarray
What is it?
Maximum Product Subarray is a problem where you find the contiguous part of an array that has the largest product of its elements. The array can have positive, negative, and zero values. The goal is to find the highest product possible by multiplying numbers next to each other in the array.
Why it matters
This problem helps us understand how to handle arrays with both positive and negative numbers when looking for maximum results. Without this concept, we might miss the best solution because negative numbers can flip the product sign, making it tricky. It is useful in fields like finance or physics where multiplying sequences matters.
Where it fits
Before this, you should know about arrays and basic subarray problems like Maximum Sum Subarray. After this, you can learn more complex dynamic programming problems and optimization techniques.
Mental Model
Core Idea
Track both the maximum and minimum products at each step because a negative number can turn a small minimum product into a large maximum product.
Think of it like...
Imagine walking on a path where stepping on a slippery stone (negative number) can flip your direction. Sometimes slipping backward (negative product) can help you jump forward farther later.
Array: [2, -3, 4, -1]

Step-by-step tracking:
Index: 0 | MaxProd: 2 | MinProd: 2 | Result: 2
Index: 1 | MaxProd: max(-3, 2*-3, 2*-3) = -3 | MinProd: min(-3, 2*-3, 2*-3) = -6 | Result: 2
Index: 2 | MaxProd: max(4, -3*4, -6*4) = 24 | MinProd: min(4, -3*4, -6*4) = -24 | Result: 24
Index: 3 | MaxProd: max(-1, 24*-1, -24*-1) = 24 | MinProd: min(-1, 24*-1, -24*-1) = -24 | Result: 24

Final max product subarray = 24
Build-Up - 6 Steps
1
FoundationUnderstanding Subarrays and Products
🤔
Concept: Learn what a subarray is and how to calculate the product of its elements.
A subarray is a continuous part of an array. For example, in [1, 2, 3], subarrays include [1], [2], [3], [1,2], [2,3], and [1,2,3]. To find the product of a subarray, multiply all its elements. For [2, 3], product is 2*3=6.
Result
You can identify any subarray and calculate its product.
Understanding subarrays and their products is the base for solving maximum product subarray problems.
2
FoundationChallenges with Negative Numbers and Zero
🤔
Concept: Recognize how negative numbers and zero affect product calculations.
Negative numbers flip the sign of the product. For example, product of [2, -3] is -6, but adding another -1 flips it back to positive 6. Zero resets the product to zero, breaking the subarray continuity.
Result
You see that negative numbers can turn small products into large ones and zeros reset the product.
Knowing how negatives and zeros behave helps us track products carefully to find the maximum.
3
IntermediateTracking Maximum and Minimum Products
🤔Before reading on: Do you think tracking only the maximum product so far is enough to solve this problem? Commit to yes or no.
Concept: Keep track of both the maximum and minimum products at each step to handle negative numbers.
At each element, calculate three values: the current element alone, current element times previous max product, and current element times previous min product. Update max and min products accordingly. This way, a negative number can turn the min product into a new max product.
Result
You can handle negative numbers correctly and find the maximum product subarray.
Tracking both max and min products prevents missing large products caused by negative numbers flipping signs.
4
IntermediateDynamic Programming Approach
🤔Before reading on: Will storing only the max product at each step allow you to find the maximum product subarray? Commit to yes or no.
Concept: Use dynamic programming to update max and min products at each index efficiently.
Initialize maxProd, minProd, and result with the first element. Iterate through the array updating maxProd and minProd using the current element and previous values. Update result if maxProd is greater. This avoids checking all subarrays explicitly.
Result
The algorithm runs in O(n) time and finds the maximum product subarray efficiently.
Dynamic programming reduces complexity by reusing previous computations instead of brute force.
5
AdvancedHandling Zeroes and Resetting Products
🤔Before reading on: Should the algorithm reset max and min products when encountering zero? Commit to yes or no.
Concept: When zero appears, reset max and min products to 1 or current element to start fresh subarrays.
Zero breaks the product chain. When zero is found, reset maxProd and minProd to 1 or the next element to avoid carrying zero forward. Also, consider zero itself as a candidate for max product.
Result
The algorithm correctly handles zeros and finds max product subarrays that start after zeros.
Resetting at zero prevents zero from dragging down future products and allows fresh calculations.
6
ExpertOptimizing Space and Understanding Edge Cases
🤔Before reading on: Can you solve this problem using only constant extra space? Commit to yes or no.
Concept: Use variables instead of arrays to store max and min products, and carefully handle edge cases like all negatives or single element arrays.
Instead of arrays, keep only current maxProd, minProd, and result variables. Update them as you iterate. Handle cases where array length is 1 or all elements are negative. This reduces memory use and improves speed.
Result
The solution is optimal in time and space, and robust for all input cases.
Constant space optimization and edge case handling make the solution practical for real-world use.
Under the Hood
The algorithm maintains two running products: the maximum and minimum product ending at the current position. This is because multiplying by a negative number swaps max and min. At each step, it updates these two values by comparing the current element, current element times previous max, and current element times previous min. The global maximum is updated accordingly. This avoids checking all subarrays explicitly and runs in linear time.
Why designed this way?
The design leverages the insight that negative numbers can flip the sign of the product, so tracking only the maximum is insufficient. Early brute force methods checked all subarrays, which was slow. This approach balances efficiency and correctness by using dynamic programming and sign tracking.
Input Array: [a0, a1, a2, ..., an]

For each index i:
  ┌─────────────────────────────┐
  │ Calculate candidates:        │
  │ 1) a[i]                     │
  │ 2) maxProd_prev * a[i]      │
  │ 3) minProd_prev * a[i]      │
  └─────────────┬───────────────┘
                │
       ┌────────┴────────┐
       │                 │
  Update maxProd      Update minProd
       │                 │
       └────────┬────────┘
                │
         Update global max result
                │
               Next i
Myth Busters - 3 Common Misconceptions
Quick: Is tracking only the maximum product at each step enough to find the maximum product subarray? Commit to yes or no.
Common Belief:Tracking only the maximum product so far is enough to solve the problem.
Tap to reveal reality
Reality:You must track both maximum and minimum products because a negative number can turn a minimum product into a maximum.
Why it matters:Ignoring the minimum product causes missing the maximum product subarray when negatives flip signs.
Quick: Does encountering zero always mean the maximum product is zero? Commit to yes or no.
Common Belief:Zero always resets the maximum product to zero and ends the subarray.
Tap to reveal reality
Reality:Zero resets the product chain, but the maximum product can be from subarrays before or after zero, or zero itself if it's the largest.
Why it matters:Not handling zero properly leads to incorrect maximum product calculations.
Quick: Can the maximum product subarray be a single negative number if all numbers are negative? Commit to yes or no.
Common Belief:The maximum product subarray must have multiple elements to be large.
Tap to reveal reality
Reality:If all numbers are negative, the maximum product can be a single negative number, especially if the array length is one.
Why it matters:Assuming multiple elements are needed can cause wrong answers in edge cases.
Expert Zone
1
When a negative number is encountered, swapping max and min products before updating is crucial to maintain correctness.
2
The algorithm can be adapted to find the subarray itself by tracking start and end indices along with products.
3
Handling integer overflow in languages like C requires careful consideration when products become very large or very small.
When NOT to use
This approach is not suitable when the array contains floating-point numbers with precision issues or when the problem requires non-contiguous elements. In such cases, other algorithms or approximations are better.
Production Patterns
In production, this algorithm is used in financial modeling to find periods of maximum growth or loss, in signal processing to detect strong signals, and in competitive programming as a classic dynamic programming example.
Connections
Maximum Sum Subarray (Kadane's Algorithm)
Builds-on
Understanding maximum sum subarray helps grasp the idea of tracking running maximums, but maximum product subarray adds complexity with sign changes.
Dynamic Programming
Same pattern
This problem is a classic example of dynamic programming where solutions build on previous computations efficiently.
Stock Market Analysis
Application
Finding maximum product subarrays relates to finding best periods for investment growth, showing how algorithms apply to real-world finance.
Common Pitfalls
#1Tracking only the maximum product and ignoring the minimum product.
Wrong approach:int maxProd = nums[0]; int result = nums[0]; for (int i = 1; i < n; i++) { maxProd = max(nums[i], maxProd * nums[i]); if (maxProd > result) result = maxProd; }
Correct approach:int maxProd = nums[0], minProd = nums[0], result = nums[0]; for (int i = 1; i < n; i++) { if (nums[i] < 0) { int temp = maxProd; maxProd = minProd; minProd = temp; } maxProd = max(nums[i], maxProd * nums[i]); minProd = min(nums[i], minProd * nums[i]); if (maxProd > result) result = maxProd; }
Root cause:Not realizing that negative numbers can flip the maximum and minimum products.
#2Not resetting products when zero is encountered.
Wrong approach:int maxProd = nums[0], minProd = nums[0], result = nums[0]; for (int i = 1; i < n; i++) { maxProd = max(nums[i], maxProd * nums[i]); minProd = min(nums[i], minProd * nums[i]); if (maxProd > result) result = maxProd; }
Correct approach:int maxProd = nums[0], minProd = nums[0], result = nums[0]; for (int i = 1; i < n; i++) { if (nums[i] == 0) { maxProd = 1; minProd = 1; if (result < 0) result = 0; continue; } if (nums[i] < 0) { int temp = maxProd; maxProd = minProd; minProd = temp; } maxProd = max(nums[i], maxProd * nums[i]); minProd = min(nums[i], minProd * nums[i]); if (maxProd > result) result = maxProd; }
Root cause:Forgetting that zero breaks the product chain and must reset tracking variables.
Key Takeaways
Maximum Product Subarray requires tracking both maximum and minimum products at each step due to negative numbers flipping signs.
Dynamic programming allows efficient O(n) time solutions by reusing previous computations instead of brute force.
Zeros reset the product chain and must be handled by resetting tracking variables to avoid incorrect results.
Edge cases like all negative numbers or single-element arrays must be carefully considered for correct answers.
Optimizing space by using variables instead of arrays makes the solution practical for real-world applications.

Practice

(1/5)
1. What does the Maximum Product Subarray problem ask you to find in an array of integers?
easy
A. The subarray with the largest difference between elements
B. The contiguous subarray with the largest sum of its elements
C. The subarray with the smallest product of its elements
D. The contiguous subarray with the largest product of its elements

Solution

  1. Step 1: Understand the problem and differentiate from similar problems

    The problem asks for a contiguous part of the array where the product of all elements is the highest possible. Unlike maximum sum subarray, this problem focuses on product, which can be affected by negative numbers and zeros.
  2. Final Answer:

    The contiguous subarray with the largest product of its elements -> Option D
  3. Quick Check:

    Maximum product subarray = largest product subarray [OK]
Hint: Focus on product, not sum, for this problem [OK]
Common Mistakes:
  • Confusing product with sum
  • Ignoring negative numbers impact
  • Thinking subarray can be non-contiguous
2. Which of the following is the correct way to declare variables to track the maximum and minimum products at each step in C for the Maximum Product Subarray problem?
easy
A. int maxProd = 1, minProd = 1;
B. int maxProd, minProd = 0;
C. int maxProd = 0, minProd = 0;
D. int maxProd = -1, minProd = -1;

Solution

  1. Step 1: Initialize maxProd and minProd properly and check alternatives

    Both maxProd and minProd should start at 1 because multiplying by 1 does not change the product. Other initializations use zero (nullifies products), negative values, or leave variables uninitialized leading to incorrect calculations or undefined behavior.
  2. Final Answer:

    int maxProd = 1, minProd = 1; -> Option A
  3. Quick Check:

    Initialize maxProd and minProd to 1 [OK]
Hint: Start max and min product as 1 to avoid zero multiplication [OK]
Common Mistakes:
  • Initializing maxProd or minProd to 0
  • Not initializing both variables
  • Using negative initial values
3. What is the output of the following C code snippet for the array int arr[] = {2, 3, -2, 4};?
int maxProductSubarray(int* nums, int numsSize) {
    int maxProd = nums[0], minProd = nums[0], result = nums[0];
    for (int i = 1; i < numsSize; i++) {
        if (nums[i] < 0) {
            int temp = maxProd;
            maxProd = minProd;
            minProd = temp;
        }
        maxProd = (nums[i] > maxProd * nums[i]) ? nums[i] : maxProd * nums[i];
        minProd = (nums[i] < minProd * nums[i]) ? nums[i] : minProd * nums[i];
        if (maxProd > result) result = maxProd;
    }
    return result;
}

int main() {
    int arr[] = {2, 3, -2, 4};
    int size = sizeof(arr) / sizeof(arr[0]);
    printf("%d", maxProductSubarray(arr, size));
    return 0;
}
medium
A. 4
B. 6
C. -2
D. 24

Solution

  1. Step 1: Trace the loop and determine final result

    Start with maxProd=2, minProd=2, result=2. - i=1 (3): maxProd=max(3,2*3)=6, minProd=min(3,2*3)=3, result=6 - i=2 (-2): swap to maxProd=3, minProd=6; maxProd=max(-2,3*(-2))=-2, minProd=min(-2,6*(-2))=-12, result=6 - i=3 (4): maxProd=max(4,-2*4)=4, minProd=min(4,-12*4)=-48, result=6 The maximum product found is 6 from subarray [2,3].
  2. Final Answer:

    6 -> Option B
  3. Quick Check:

    Max product subarray = 6 [OK]
Hint: Swap max and min when negative number encountered [OK]
Common Mistakes:
  • Not swapping max and min on negative number
  • Confusing max product with sum
  • Incorrectly updating result
4. Identify the bug in the following C code snippet for Maximum Product Subarray and select the correct fix:
int maxProductSubarray(int* nums, int numsSize) {
    int maxProd = 1, minProd = 1, result = nums[0];
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] < 0) {
            int temp = maxProd;
            maxProd = minProd;
            minProd = temp;
        }
        maxProd = (nums[i] > maxProd * nums[i]) ? nums[i] : maxProd * nums[i];
        minProd = (nums[i] < minProd * nums[i]) ? nums[i] : minProd * nums[i];
        if (maxProd > result) result = maxProd;
    }
    return result;
}
medium
A. Initialize maxProd and minProd with nums[0] and start loop from i=1
B. Remove the swap of maxProd and minProd when nums[i] < 0
C. Initialize result to 1 instead of nums[0]
D. Change the loop to run from i=1 to numsSize-1 without other changes

Solution

  1. Step 1: Check initialization and loop start; analyze other options

    maxProd and minProd should start as nums[0] to correctly handle the first element. Loop should start from i=1 to avoid reprocessing first element. Removing swap breaks handling of negative numbers. Initializing result to 1 is incorrect if nums[0] is negative. Changing loop start without fixing initialization causes errors.
  2. Final Answer:

    Initialize maxProd and minProd with nums[0] and start loop from i=1 -> Option A
  3. Quick Check:

    Proper initialization and loop start fix bug [OK]
Hint: Initialize with first element, loop from second element [OK]
Common Mistakes:
  • Starting loop from 0 with maxProd=1
  • Not swapping max and min on negative
  • Wrong initialization of result
5. Given the array int arr[] = {-1, -3, -10, 0, 60};, what is the maximum product of any contiguous subarray?
hard
A. 1800
B. 0
C. 60
D. -1

Solution

  1. Step 1: Analyze subarrays and their products

    Relevant products: [60]=60, [-3,-10]=30, [-1,-3]=3, [-1,-3,-10]=-30, [-10]=-10, subarrays crossing or including 0=0. No larger contiguous product exists (e.g. [-3,-10,60] skips 0, invalid).
  2. Final Answer:

    60 -> Option C
  3. Quick Check:

    Max product subarray = 60 [OK]
Hint: Check negative pairs and zeros carefully [OK]
Common Mistakes:
  • Thinking non-contiguous subarrays like [-3,-10,60] are valid
  • Choosing [-3,-10]=30 instead of 60
  • Confusing zero as max product
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard