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 operation.
2 <= nums.length <= 105-30 <= nums[i] <= 30answer[i] is guaranteed to fit in a 32-bit integer.Can you solve the problem in $O(1)$ extra space complexity? (The output array does not count as extra space for space complexity analysis.)
For each of the n elements, we iterate through all n elements again, resulting in total operations.
No auxiliary data structures are used beyond the output array.
The brute force approach calculates the product for each index by iterating through all other elements in a nested loop. For each position i, we initialize a product of 1 and multiply every element nums[j] where j ≠ i, appending the result to the output array. While correct, this quadratic solution does not satisfy the problem's requirement.
We make three linear passes — one to build prefix, one to build suffix, and one to compute the result — each .
Two auxiliary arrays of size n (prefix and suffix) are allocated beyond the output array.
This approach precomputes two auxiliary arrays: prefix[i] holds the product of all elements before index i, and suffix[i] holds the product of all elements after index i. We fill prefix with a forward pass and suffix with a backward pass, then combine them so that result[i] = prefix[i] * suffix[i], giving the product of all elements except the one at i.
Two linear passes are made over the array — one forward for prefix products and one backward for suffix products.
Only two scalar variables (prefix and suffix) are used beyond the output array.
This solution eliminates the two auxiliary arrays from Solution 2 by writing prefix products directly into the result array. In a forward pass, result[i] is set to the running prefix product before index i. In a backward pass, a running suffix variable is multiplied into each result[i], overlaying the suffix product on top of the already-stored prefix — achieving extra space.
A single pass of n iterations covers the entire array, with work per iteration.
Only two scalar variables (prefix and suffix) are used beyond the output array.
This solution compresses Solution 3's two passes into a single loop by simultaneously updating the result from both ends of the array. In each iteration i, the front pointer multiplies the running prefix into result[i] while the back pointer multiplies the running suffix into result[n-1-i], interleaving the prefix and suffix accumulation in one traversal.
| Approach | Rating | Time Complexity | Space Complexity | Advantages | Disadvantages |
|---|---|---|---|---|---|
| Brute Force | extra space | Simplest to understand; no extra data structures needed | time fails the problem's requirement | ||
| Prefix and Suffix Arrays | Clear, intuitive separation of prefix and suffix logic into two explicit arrays | ⚠️ Requires extra space for the two auxiliary arrays | |||
| Two-Pass Prefix & Suffix | extra space | Optimal time and space; two clean, readable passes over the array | Requires two passes instead of one | ||
| Single-Pass Prefix & Suffix | extra space | Same optimal complexity as Solution 3 but completes in a single loop | Interleaved bidirectional index updates reduce readability |
The optimal approach for this problem is Solution 3: Two-Pass Prefix & Suffix, which achieves time complexity and extra space. It eliminates the auxiliary arrays of Solution 2 by writing prefix products directly into the result array and overlaying suffix products in a backward pass, satisfying both the time requirement and the space follow-up. Solutions marked with ⚠️ do not meet the follow-up requirement and are not recommended.
class Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: result = []
# Loop through each element in the input list for i in range(len(nums)): product = 1
# Loop through the list again to calculate the product of all elements except the current one for j in range(len(nums)): if i != j: product *= nums[j]
result.append(product)
return resultclass Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: n = len(nums) result = [1] * n
prefix = 1 # Initialize prefix product
# Calculate the prefix product for each element for i in range(n): result[i] *= prefix prefix *= nums[i]
suffix = 1 # Initialize suffix product
# Calculate the suffix product for each element and multiply it with the prefix product for i in range(n - 1, -1, -1): result[i] *= suffix suffix *= nums[i]
return resultclass Solution: def productExceptSelf(self, nums: List[int]) -> List[int]: n = len(nums) result = [1] * n prefix = 1 suffix = 1
for i in range(n): # Update the result for the current index with the prefix product result[i] *= prefix prefix *= nums[i]
# Update the result for the current index from the end with the suffix product result[n - 1 - i] *= suffix suffix *= nums[n - 1 - i]
return result