Saturday, 7 Mar 2026

LeetCode 238: Product of Array Except Self Solution Explained

Understanding the Problem

Given an integer array nums, return an array answer where answer[i] equals the product of all elements except nums[i]. The challenge? Solve without division in O(n) time with O(1) extra space (excluding output array). This constraint forces us beyond brute-force approaches.

Why Division Is Forbidden

The intuitive solution - multiply all elements then divide by nums[i] - fails because:

  1. Division by zero crashes when nums[i] = 0
  2. Problem explicitly prohibits division operations
  3. Real-world systems often restrict division due to higher computational cost

Brute-Force Approach (Not Optimal)

The initial nested loop solution:

  1. For each index i:
    • Initialize product = 1
    • For each index j:
      • If i ≠ j: product *= nums[j]
  2. Store product in answer[i]

Time Complexity: O(n²) - Unacceptable for large inputs (n ≤ 10⁵)
Space Complexity: O(1) - But fails time constraints

Optimal Two-Pass Solution

Core Insight

answer[i] = (product of left elements) × (product of right elements)

  • Left product: Prefix up to i-1
  • Right product: Suffix from i+1

Step-by-Step Execution

  1. Forward pass (Calculate left products):

    • Initialize answer[0] = 1
    • For i from 1 to n-1:
      answer[i] = answer[i-1] × nums[i-1]
  2. Backward pass (Incorporate right products):

    • Initialize right_product = 1
    • For i from n-1 down to 0:
      *answer[i] = right_product
      *right_product = nums[i]

Complexity Analysis

  • Time: O(n) - Two linear passes
  • Space: O(1) - Only variables (output array excluded)

Edge Case Handling

  • Zero values: Naturally handled since multiplication propagates zeros
  • Single element: Returns [1] since no other elements to multiply

Implementation Walkthrough

Consider nums = [1, 2, 3, 4]:

Forward Pass (Left products):

  • i=0: answer[0] = 1 (no left elements)
  • i=1: answer[1] = 1 × 1 = 1
  • i=2: answer[2] = 1 × 2 = 2
  • i=3: answer[3] = 2 × 3 = 6

Backward Pass (Apply right products):

  • i=3: right_product=1 → answer[3]=6×1=6; Update right_product=1×4=4
  • i=2: answer[2]=2×4=8; Update right_product=4×3=12
  • i=1: answer[1]=1×12=12; Update right_product=12×2=24
  • i=0: answer[0]=1×24=24

Result: [24, 12, 8, 6]

Key Optimization Insights

  1. Reuse output array: Store left products directly in answer
  2. Single variable for right products: Compute on-the-fly during reverse pass
  3. Avoid precomputation: Merge steps to eliminate extra arrays

Common Pitfalls to Avoid

  • Modifying nums during processing: Always treat as read-only
  • Ignoring space constraints: Using O(n) extra space fails optimization
  • Incorrect initialization: right_product must start at 1

Advanced Follow-Ups

  1. Product with division allowed: How would solution change?
  2. Multi-dimensional arrays: Extend this approach to matrices
  3. Streaming data: Handle infinite input streams (sliding window variant)

Actionable Implementation Checklist

  1. Initialize answer array with size n
  2. Set answer[0] = 1
  3. Forward pass: Compute left products
  4. Set right_product = 1
  5. Backward pass: Multiply right products into answer
  6. Return answer

Practice Recommendation:
Reimplement this solution on LeetCode immediately - internalizing the two-pass pattern is critical for array manipulation problems.

"Which step in the backward pass do you anticipate being most challenging? Share your implementation hurdles below!"

Resources for Mastery:

  • Book: "Elements of Programming Interviews" (Azetliyanos) - Chapter 5
  • Tool: LeetCode Playground - Test edge cases interactively
  • Community: r/leetcode - Discuss variants like "product of k nearest neighbors"
PopWave
Youtube
blog