Product of Array Except Self

Given an integer array nums, build an array answer of the same length where answer[i] is the product of every element of nums except nums[i].

You may not use division, and your solution should run in O(n) time. Every product of a prefix or suffix of nums is guaranteed to fit in a 32-bit signed integer, so no overflow handling is needed.

As an extra challenge, try to use only O(1) extra space; the output array does not count towards that.

Example 1

Input: nums = [2,3,4,5] Output: [60,40,30,24] Why: answer[0] = 3·4·5 = 60, answer[1] = 2·4·5 = 40, answer[2] = 2·3·5 = 30, answer[3] = 2·3·4 = 24.

Example 2

Input: nums = [1,-2,0,4] Output: [0,0,-8,0] Why: Only the position holding the 0 has a non-zero result: 1·(-2)·4 = -8. Every other product includes the 0.

Example 3

Input: nums = [0,5,0,2] Output: [0,0,0,0] Why: With two zeros, every product skips at most one of them, so all results are 0.

Constraints

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • The product of any prefix or suffix of nums fits in a 32-bit signed integer.

Pattern Path · Math, Bits & Strings · problem 36 of 169

The product of everything except nums[i] splits into two parts: what lies to the left of i and what lies to the right.
Could you precompute, for every index, the product of all elements before it? And all elements after it?
One left-to-right pass can write the left products straight into the answer array. A second right-to-left pass can multiply in the right products using a single running variable.
Target: O(n) time, O(1) extra (the output array is not counted) extra space.

Start simple

For each index, multiply all the other elements with an inner loop: O(n²) time, O(1) extra space.

The key idea

For index i, the wanted product is (product of nums[0..i-1]) × (product of nums[i+1..n-1]). Both factors are prefix/suffix products, and those can be built incrementally: the left product for i + 1 is the left product for i times nums[i].

So walk left to right with a running value prefix (starting at 1), store it in answer[i], then multiply nums[i] into it. After this pass answer[i] holds everything to the left of i. Walk back right to left with a running suffix (starting at 1), multiply it into answer[i], then multiply nums[i] into suffix. Now each slot has both halves.

This avoids division entirely, which matters: dividing the total product by nums[i] breaks as soon as the array contains a zero. Zeros need no special case here, because each one simply lands in the left or right half of the other positions' products.

Complexity

  • Time: O(n)
  • Space: O(1) extra (the output array is not counted)

Python

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        answer = [1] * n

        # Left pass: answer[i] = product of everything before i.
        prefix = 1
        for i in range(n):
            answer[i] = prefix
            prefix *= nums[i]

        # Right pass: multiply in the product of everything after i.
        suffix = 1
        for i in range(n - 1, -1, -1):
            answer[i] *= suffix
            suffix *= nums[i]

        return answer

JavaScript

var productExceptSelf = function(nums) {
  const n = nums.length;
  const answer = new Array(n).fill(1);

  // Left pass: answer[i] = product of everything before i.
  let prefix = 1;
  for (let i = 0; i < n; i++) {
    answer[i] = prefix;
    prefix *= nums[i];
  }

  // Right pass: multiply in the product of everything after i.
  let suffix = 1;
  for (let i = n - 1; i >= 0; i--) {
    answer[i] *= suffix;
    suffix *= nums[i];
  }

  return answer;
};

What the interviewer is checking

The interviewer wants to see the prefix/suffix decomposition and whether you can squeeze it into the output array instead of allocating two helper arrays.

Mistakes to avoid

  • Using total product divided by nums[i]: forbidden, and it fails on zeros.
  • Off-by-one: answer[i] must exclude nums[i], so store the running product before multiplying the current element in.
  • Allocating separate left and right arrays works but misses the O(1) extra-space goal.

Follow-ups to expect

  • What if division were allowed? (Count zeros; handle 0, 1, 2+ zeros.)
  • What if products could overflow? (Big integers or modular arithmetic.)
  • How would you answer range products for many queries? (Prefix products or segment tree.)

In real software

The same left-pass/right-pass trick computes "everything except this one" aggregates, such as leave-one-out statistics in data analysis or gradients of a product in automatic differentiation.

Practice next

Next Post Previous Post
No Comment
Add Comment
comment url