nums[i]
, we need to calculate the product of all other elements in the array, excluding nums[i]
.nums[i]
, iterate over every other element in the array, multiplying the elements together (excluding the element at index i
).ans
.nums[i]
is stored in ans[i]
.ans
array.
While the brute force approach works, it has a time complexity of O(n^2)
because it loops through the array for each element and performs an inner loop for every other element. This can become very inefficient for large input sizes. The solution is slow for larger arrays, especially when n
is large (e.g., n = 10^5
).
left
array.right
array.left
and right
values. So, the final result for each element is ans[i] = left[i] * right[i]
.ans
array.
The "Product of Array Except Self" problem asks us to build a new array such that each element at index i
is the product of all the elements in the original array nums
, except nums[i]
itself.
Importantly, we are not allowed to use division in this problem, and we must solve it with a time complexity of O(n)
.
For example, given the input [1, 2, 3, 4]
, the output should be [24, 12, 8, 6]
. Here's why:
This problem is widely used in technical interviews and tests your ability to reason about array transformations, prefix and suffix accumulation, and in-place space optimization. It also teaches you how to compute results without violating constraints such as avoiding division or additional space usage.
The brute force method involves creating a nested loop where for every element in the array, we iterate through the entire array again and multiply all elements except the one at index i
.
We store the result in a new output array.
While this approach is easy to understand, it has a time complexity of O(n²)
, which makes it inefficient for large arrays.
The optimal approach avoids division and nested loops by breaking the task into two linear passes:
The trick is to re-use the result array to avoid extra space: we fill it with left products first, and during the right pass, we keep a running right product that multiplies into the result.
Input: [1, 2, 3, 4]
Step 1: Compute prefix products
We initialize res = [1, _, _, _]
res[1] = res[0] * nums[0] = 1 * 1 = 1
res[2] = res[1] * nums[1] = 1 * 2 = 2
res[3] = res[2] * nums[2] = 2 * 3 = 6
res = [1, 1, 2, 6]
Step 2: Compute suffix products and combine
Initialize right = 1
and go from right to left:
res[3] = res[3] * right = 6 * 1 = 6
, then right = right * nums[3] = 1 * 4 = 4
res[2] = res[2] * right = 2 * 4 = 8
, then right = 4 * 3 = 12
res[1] = res[1] * right = 1 * 12 = 12
, then right = 12 * 2 = 24
res[0] = res[0] * right = 1 * 24 = 24
[24, 12, 8, 6]
Time Complexity: O(n) — We perform two linear passes through the array.
Space Complexity: O(1) extra space if we exclude the result array, which is required by the output anyway. Otherwise, it is O(n) for the result.
The “Product of Array Except Self” problem is a perfect example of how clever precomputation techniques can drastically improve algorithm performance. By using prefix and suffix products, we avoid costly nested loops and deliver an elegant linear-time solution without using division. Understanding this pattern unlocks similar strategies for many other problems involving aggregate values with element exclusions.