Skip to main content

238. Product of Array Except Self

mediumAsked at JPMorgan

For each index, compute the product of all other elements without using division and in O(n) time. JPMorgan asks this on SDE onsites because the optimal prefix-and-suffix-product solution is the smallest interesting use of the 'two passes with O(1) extra space beyond the output' pattern.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in JPMorgan loops.

  • Glassdoor (2026-Q1)Recurring JPMorgan SDE onsite array problem in Q1 2026 reviews.
  • LeetCode (2026-Q1)Tagged JPMorgan on the LeetCode company tag page.
  • Reddit r/cscareerquestions (2025-12)JPMC senior SDE write-up: 'they explicitly forbade division and asked for O(1) extra space'.

Problem

Given an integer array nums, return an array answer such that answer[i] is equal to the product of all the elements of nums except nums[i]. The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. You must write an algorithm that runs in O(n) time and without using the division operator.

Constraints

  • 2 <= nums.length <= 10^5
  • -30 <= nums[i] <= 30
  • The output array does not count as extra space for space complexity analysis.

Examples

Example 1

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

Example 2

Input
nums = [-1,1,0,-3,3]
Output
[0,0,9,0,0]

Approaches

1. Brute force

For each i, multiply every other element.

Time
O(n^2)
Space
O(n) for output
function productExceptSelfBrute(nums) {
  const n = nums.length;
  const out = new Array(n);
  for (let i = 0; i < n; i++) {
    let p = 1;
    for (let j = 0; j < n; j++) {
      if (i !== j) p *= nums[j];
    }
    out[i] = p;
  }
  return out;
}

Tradeoff: Conceptually simplest but TLEs at n=10^5. Useful only as a baseline.

2. Two arrays: prefix and suffix products

Build prefix[i] = product of nums[0..i-1] and suffix[i] = product of nums[i+1..n-1]. Output[i] = prefix[i] * suffix[i].

Time
O(n)
Space
O(n) auxiliary
function productExceptSelfTwoArrays(nums) {
  const n = nums.length;
  const prefix = new Array(n).fill(1);
  const suffix = new Array(n).fill(1);
  for (let i = 1; i < n; i++) prefix[i] = prefix[i - 1] * nums[i - 1];
  for (let i = n - 2; i >= 0; i--) suffix[i] = suffix[i + 1] * nums[i + 1];
  const out = new Array(n);
  for (let i = 0; i < n; i++) out[i] = prefix[i] * suffix[i];
  return out;
}

Tradeoff: O(n) time but O(n) auxiliary space on top of the output. A great intermediate explanation before the in-place version.

3. Single output array, two passes, O(1) auxiliary (optimal)

First pass fills output[i] with prefix product. Second pass walks backward maintaining a running suffix product, multiplying into the output.

Time
O(n)
Space
O(1) (the output is not counted)
function productExceptSelf(nums) {
  const n = nums.length;
  const out = new Array(n);
  let pre = 1;
  for (let i = 0; i < n; i++) {
    out[i] = pre;
    pre *= nums[i];
  }
  let suf = 1;
  for (let i = n - 1; i >= 0; i--) {
    out[i] *= suf;
    suf *= nums[i];
  }
  return out;
}

Tradeoff: O(n) time and O(1) auxiliary — the canonical answer for the LeetCode constraint. Reuses the output array as the prefix store, then walks backward with a single suffix variable.

JPMorgan-specific tips

JPMorgan interviewers ask 'no division and O(1) extra space' as the explicit constraint pair. Articulate both before writing code: 'no division because zeros cause divide-by-zero and float drift on negative inputs; O(1) extra so the algorithm is in-place on the output array.' The candidates who skip that narration tend to produce the two-array version and stop, missing the in-place optimisation.

Common mistakes

  • Reaching for division (totalProduct / nums[i]) — explicitly forbidden and breaks on any zero element.
  • Computing total product and dividing — same problem, fails on zeros.
  • Special-casing zeros with two passes (count zeros, branch on count) — works but loses points for not seeing the prefix/suffix invariant.
  • Using the second pass to overwrite output[i] before reading the previous suffix — order matters.

Follow-up questions

An interviewer at JPMorgan may pivot to one of these next:

  • What if division were allowed and the input is guaranteed non-zero? (Single pass with total product / nums[i].)
  • What if you must support a streaming feed and answer 'product except current' on every insert?
  • Maximum product subarray (LC 152) — different problem, similar prefix/suffix flavour.
  • What if numbers can be very large (BigInt)?

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why does the in-place version need exactly two passes?

On the first pass, output[i] is set to the product of everything strictly to the left of i. On the second (backward) pass, you multiply in the product of everything strictly to the right. Their product is everything except nums[i]. You cannot do it in a single forward pass because the suffix product is not known until you have seen the entire array.

Is the suffix variable the only state needed in the backward pass?

Yes. The first pass left prefix[i] in output[i]. The backward pass needs to multiply that by suffix[i], and a single scalar 'product of everything seen so far in the backward walk' is sufficient — no extra array.

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

Drill Product of Array Except Self and other JPMorgan interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →