Product of Array Except Self
Build an array where position i holds the product of every value in nums except nums[i], without division.
- 2 <= nums.length <= 10⁵
- -30 <= nums[i] <= 30
- The input is generated such that answer[i] is guaranteed to fit in a 32-bit integer.
Intuition
Product of array except self returns an array where each position holds the product of every other element. Two constraints shape the solution: division is forbidden, and the output array does not count toward the space complexity.
The division ban is not arbitrary. Dividing the total product by each element breaks on zeros, and handling one zero, two zeros, and no zeros separately is exactly the messy case analysis the constraint exists to prevent.
The clean approach splits each answer into two halves:
- The product of everything except position i is the product of everything to its left times the product of everything to its right.
So two passes suffice. The first walks left to right, writing into the output the running product of everything before each position. The second walks right to left, multiplying each entry by the running product of everything after it.
The second pass needs only a single variable for the right-hand running product, not another array — which is how the solution reaches O(1) extra space.
Both running products start at 1, not 0. Starting at zero makes every result zero, which is the most common bug here.
The boundaries handle themselves: position 0 has nothing to its left, and its left product stays at the initial 1, which is correct since an empty product is 1.
Zeros need no special handling at all. A single zero makes every other position zero automatically, and two zeros make everything zero — both fall out of the multiplication without a branch.
The cost is O(n) time with O(1) extra space, excluding the output as the problem allows.
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.
Approach
Before reading on: price up what the direct approach costs here, then ask what you would need to remember from the left to avoid re-scanning. Aim for O(n) time and O(1) extra space.
Understand the division ban
Dividing the total product breaks on zeros, forcing separate cases for one zero, two zeros, and none. The constraint exists to rule out that mess.
Split into left and right
Each answer is the product of everything left of i times everything right of it. This decomposition is what makes two passes sufficient.
Sweep left to right
Write into the output the running product of all elements before each position. Position 0 receives the initial value, since nothing precedes it.
Start both products at one
Initialise the running products to 1, not 0. Starting at zero makes every result zero — the most common bug in this problem.
Sweep right to left
Multiply each output entry by the running product of everything after it, using a single variable rather than a second array.
Let zeros resolve themselves
No special handling is needed. One zero makes every other position zero automatically; two zeros make everything zero — both fall out of the multiplication.
Cost of the approach
Two linear passes give O(n) time and O(1) extra space, with the output array excluded as the problem permits.
Solution & live demo
Common pitfalls
Using division despite zero values
answer[i] = total_product // nums[i]
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
prefix *= nums[i] answer[i] = prefix
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
suffix *= nums[i] answer[i] *= suffix
answer[i] *= suffix suffix *= nums[i]
The suffix must represent positions strictly to the right when it is multiplied into answer[i].
Edge cases
[1, 2, 0, 4]The zero index combines non-zero prefix and suffix products, while every other position receives zero from one side.
Every index has a zero on its left or right, so both passes correctly produce all zeros.
Prefix and suffix multiplication preserve signs without any special branch.