Skip to main content

Product of Array Except Self

How to use prefix and suffix products to build the local answer for each index from the surrounding context.

Given an integer array nums, return an array answer such that answer[i] is equal to the product of all elements of nums except nums[i].

You must do this without using division.

Example:

Input:  nums = [1,2,3,4]
Output: [24,12,8,6]

What to notice before coding

Common mistakes

Step 1 — See the forbidden shortcut

Without the restriction, the obvious idea would be:

  • compute the total product
  • divide by nums[i]

The problem forbids that.

And that makes sense. Zero complicates everything, and the exercise wants a different kind of reasoning.

Step 2 — Ask where the answer for each index comes from

For answer[i], you need the product of:

  • everything before i
  • everything after i

That suggests splitting the information in two parts.

Step 3 — Build prefixes

If answer[i] starts by storing the product to the left:

  • answer[0] = 1
  • answer[1] = nums[0]
  • answer[2] = nums[0] * nums[1]

then half of the answer is already done.

Step 4 — Multiply by suffixes

Then make a right-to-left pass:

  • keep a running product from the right
  • multiply that into answer[i]

That makes each position become:

leftPrefix * rightSuffix

The interactive editor needs JavaScript. You can still read the prompt and copy the starter code below.

Starter code

export function productExceptSelf(nums: number[]): number[] {
  // your solution here
  return []
}
solution.ts
Stuck? Hints available.

Haven't solved it yet?

Viewing the solution now may reduce learning. It's worth trying a bit more.

Open the reference solution

Without JavaScript, the reference solution is shown inline instead of in a dialog.

Solution

Final complexity

Time: O(n)

Space: O(1)

Solution 1 — Recalculate for each index

Correct, but too slow.

export function productExceptSelf(nums: number[]): number[] {
  const answer: number[] = []

  for (let index = 0; index < nums.length; index += 1) {
    let product = 1

    for (let other = 0; other < nums.length; other += 1) {
      if (other !== index) {
        product *= nums[other]
      }
    }

    answer.push(product)
  }

  return answer
}

Solution 2 — Prefix + suffix accumulators in O(n)

Now each pass accumulates half of the information.

export function productExceptSelf(nums: number[]): number[] {
  const answer = new Array(nums.length).fill(1)

  let prefix = 1
  for (let index = 0; index < nums.length; index += 1) {
    answer[index] = prefix
    prefix *= nums[index]
  }

  let suffix = 1
  for (let index = nums.length - 1; index >= 0; index -= 1) {
    answer[index] *= suffix
    suffix *= nums[index]
  }

  return answer
}

Each index receives the left product in one pass and the right product in the other.

What to say in the interview

A strong short explanation would be:

Without division, each answer should be thought of as product of the left side times product of the right side. I make one pass storing prefixes in the result array, then another pass multiplying by running suffixes. That keeps the solution O(n) without recomputing everything for each index.

That shows that you:

  • understood why division was forbidden
  • broke the problem into reusable parts
  • explained prefix/suffix as composition, not a trick

When this pattern shows up again

The same pattern comes back when you need to:

  • combine accumulated information from both sides
  • answer per index without recomputing everything
  • work with prefix sums or prefix products
  • turn a global dependency into two local passes

The point is not memorizing productExceptSelf.

The point is noticing when the answer can be built from partial accumulators.

Next challenge Merge Intervals Previous challenge Group Anagrams

Related challenges

Related articles