Question : 238. Product of Array Except Self
Medium
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.
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]
Constraints:
2 <= nums.length <= 10<sup>5</sup>
-30 <= nums[i] <= 30
The product of any prefix or suffix of
nums
is guaranteed to fit in a 32-bit integer.
Here is the solution in JavaScript :
var productExceptSelf = function(nums) {
const n = nums.length;
const output = new Array(n).fill(1);
// Get product of all elements before each index
let product = 1;
for(let i = 0; i < n; i++) {
output[i] *= product;
product *= nums[i];
}
// Get product of all elements after each index
product = 1;
for(let i = n - 1; i >= 0; i--) {
output[i] *= product;
product *= nums[i];
}
return output;
};
Let's analyze the time complexity:
The key steps are:
Initialize output array of length n - O(n)
Left to right pass:
Loop through nums array of length n - O(n)
Update product - O(1) per loop
Update output - O(1) per loop
Right to left pass:
Loop through nums array backward of length n - O(n)
Update product - O(1) per loop
Update output - O(1) per loop
So overall, the time complexity is O(n) + O(n) + O(n) = O(3n) = O(n) linear time.
Let's see how it works:
// Input
nums = [1, 2, 3, 4]
// Initialize output array
output = [1, 1, 1, 1]
// Left to right pass
product = 1
i = 0
- output[0] *= product -> output[0] = 1 * 1 = 1
- product *= nums[0] -> product = 1 * 1 = 1
i = 1
- output[1] *= product -> output[1] = 1 * 1 = 1
- product *= nums[1] -> product = 1 * 2 = 2
i = 2
- output[2] *= product -> output[2] = 1 * 2 = 2
- product *= nums[2] -> product = 2 * 3 = 6
i = 3
- output[3] *= product -> output[3] = 1 * 6 = 6
- product *= nums[4] -> product = 6 * 4 = 24
// Right to left pass
product = 1
i = 3
- output[3] *= product -> output[3] = 6 * 1 = 6
- product *= nums[3] -> product = 1 * 4 = 4
i = 2
- output[2] *= product -> output[2] = 2 * 4 = 8
- product *= nums[2] -> product = 4 * 3 = 12
i = 1
- output[1] *= product -> output[1] = 1 * 12 = 12
- product *= nums[1] -> product = 12 * 2 = 24
i = 0
- output[0] *= product -> output[0] = 1 * 24 = 24
- product *= nums[0] -> product = 24 * 1 = 24
// Final output
[24, 12, 8, 6]
Logic behin left loop:
The left loop in the productExceptSelf function is important for two reasons:
To calculate the product of all the elements to the left of each index.
To skip the element at the current index when calculating the product.
Here is what the left loop is doing:
It starts with a product of 1.
At each index i, it multiplies the product so far into output[i]. This captures the product of all elements before i.
It then multiplies nums[i] into the product. This skips nums[i] for the current index i, but includes it for future indices.
Without the left loop, we wouldn't have the product of elements before each index, and would be unable to skip the current element.
For example, consider nums = [1, 2, 3, 4]:
After the left loop:
output[0] = 1 (no elements before, so product is 1)
output[1] = 1 (only 1 before, so product is 1)
output[2] = 2 (1 * 2 before)
output[3] = 6 (1 2 3 before)
And product = 24 (product of all elements so far)
if you have any issue kindly comment below