LeetCode #238 Medium

Product of Array Except Self

Build an array where position i holds the product of every value in nums except nums[i], without division.

arrayprefix-productsuffix-product
Open on LeetCode ↗
02

Intuition

Multiplying every other element separately for each output repeats almost the same work O(n²) times. For index i, the needed factors naturally split into everything left of i and everything right of i. A forward pass can place the product of the left side into the answer, and a backward pass can multiply in a running product of the right side. Because each running product is used before the current value is included, nums[i] is excluded automatically, including when zeros are present.

How to spot this pattern

When each output combines all elements except the current one, look for a left contribution and a right contribution. Prefix and suffix accumulation avoids rebuilding those two ranges for every index and avoids the problems division has with zero.

03

Approach

1

Write each index's left product

Start prefix at 1, the product of an empty side. At index i, store the current prefix in answer[i], then multiply prefix by nums[i] for the next position. Using the value before updating is what excludes the current element.

2

Sweep backward with the right product

Start suffix at 1 and move from the final index toward zero. Multiply answer[i] by the current suffix, which contains only values strictly to the right, then include nums[i] in the suffix for the next index.

3

Let multiplication handle zeros naturally

No division or zero counting is necessary. With one zero, only its own position receives the product of the non-zero sides; with multiple zeros, every output receives a zero from at least one side. Both passes are linear and use only running variables beyond the output.

04

Solution

1class Solution:
2 def productExceptSelf(self, nums: List[int]) -> List[int]:
3 answer = [1] * len(nums)
4 prefix = 1
5 
6 for i in range(len(nums)):
7 answer[i] = prefix
8 prefix *= nums[i]
9 
10 suffix = 1
11 for i in range(len(nums) - 1, -1, -1):
12 answer[i] *= suffix
13 suffix *= nums[i]
14 
15 return answer
05

Common pitfalls

Using division despite zero values

✗ Wrong
answer[i] = total_product // nums[i]
✓ Right
answer[i] = prefix

Division is forbidden and becomes undefined at zero; separate side products work for every input.

Including the current number in the prefix

✗ Wrong
prefix *= nums[i]
answer[i] = prefix
✓ Right
answer[i] = prefix
prefix *= nums[i]

Updating first puts nums[i] into its own output, which violates the except-self requirement.

Updating the suffix before using it

✗ Wrong
suffix *= nums[i]
answer[i] *= suffix
✓ Right
answer[i] *= suffix
suffix *= nums[i]

The suffix must represent positions strictly to the right when it is multiplied into answer[i].

06

Edge cases

Exactly one zero, such as [1, 2, 0, 4]

The zero index combines non-zero prefix and suffix products, while every other position receives zero from one side.

Two or more zeros

Every index has a zero on its left or right, so both passes correctly produce all zeros.

Negative values

Prefix and suffix multiplication preserve signs without any special branch.

07

Complexity

Time
O(n)
Space
O(1) extra
The returned answer array is excluded from auxiliary space.