Product of Array Except Self
In this blog, we will discuss the "Product of Array Except Self" problem, which is a popular problem in coding interviews. We will go through the problem statement, explain the approach, and provide both brute force and optimal solutions. Additionally, we will perform a dry run of the code for better understanding and analyze the time and space complexity of each solution.
Problem Statement with Example
Given an integer array nums
, the task is to 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.
Let's consider an example to understand the problem:
Example 1:
Input: nums = [1, 2, 3, 4]
Output: [24, 12, 8, 6]
Explanation: The product of all elements except the element at index 0 is 2*3*4 = 24
. Similarly, for index 1, it is 1*3*4 = 12
, for index 2, it is 1*2*4 = 8
, and for index 3, it is 1*2*3 = 6
.
Example 2:
Input: nums = [-1, 1, 0, -3, 3]
Output: [0, 0, 9, 0, 0]
Explanation: The product of all elements except the element at index 0 is 1*0*(-3)*3 = 0
. Similarly, for index 1, it is -1*0*(-3)*3 = 0
, for index 2, it is -1*1*(-3)*3 = 9
, for index 3, it is -1*1*0*3 = 0
, and for index 4, it is -1*1*0*(-3) = 0
.

Brute Force Solution
We can solve this problem using a brute force approach by iterating over the array and calculating the product of all elements except the current one for each element. However, this approach will have a time complexity of O(n^2), which is not efficient for large arrays.
Algorithm/Pseudocode
// Brute Force Approach
1. Initialize an array 'answer' of the same length as 'nums' and fill it with 1.
2. For each element in 'nums' at index i:
a. Initialize a variable 'product' to 1.
b. For each element in 'nums' at index j:
i. If i is not equal to j, multiply 'product' by nums[j].
c. Assign 'product' to answer[i].
3. Return the 'answer' array.
Java Code for Brute Force Solution
package codeKatha;
public class ProductOfArrayExceptSelf {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] answer = new int[n];
for (int i = 0; i < n; i++) {
int product = 1;
for (int j = 0; j < n; j++) {
if (i != j) {
product *= nums[j];
}
}
answer[i] = product;
}
return answer;
}
}
Dry Run
Let's dry run the brute force solution with an example:
Input: nums = [1, 2, 3, 4]
Step 1: Initialize answer = [1, 1, 1, 1] Step 2: Iterating over each element in nums: - For i = 0: product = 1 - For j = 0: skip (i == j) - For j = 1: product = 1 * 2 = 2 - For j = 2: product = 2 * 3 = 6 - For j = 3: product = 6 * 4 = 24 - answer[0] = 24 - For i = 1: product = 1 - For j = 0: product = 1 * 1 = 1 - For j = 1: skip (i == j) - For j = 2: product = 1 * 3 = 3 - For j = 3: product = 3 * 4 = 12 - answer[1] = 12 - For i = 2: product = 1 - For j = 0: product = 1 * 1 = 1 - For j = 1: product = 1 * 2 = 2 - For j = 2: skip (i == j) - For j = 3: product = 2 * 4 = 8 - answer[2] = 8 - For i = 3: product = 1 - For j = 0: product = 1 * 1 = 1 - For j = 1: product = 1 * 2 = 2 - For j = 2: product = 2 * 3 = 6 - For j = 3: skip (i == j) - answer[3] = 6 Step 3: Return answer = [24, 12, 8, 6]
Time and Space Complexity
Time Complexity: O(n2)
- For each element, we are iterating through the entire array to calculate the product.
Space Complexity: O(n)
- We are using an extra array to store the result.
Optimized Solution
To optimize this solution, we can use two additional arrays to store the product of all elements to the left and right of each element. This will allow us to calculate the final product for each element in O(n) time.
Algorithm/Pseudocode
// Optimized Approach
1. Initialize two arrays, 'leftProducts' and 'rightProducts', of the same length as 'nums' and fill them with 1.
2. Initialize an array 'answer' of the same length as 'nums' and fill it with 1.
3. Fill 'leftProducts' such that leftProducts[i] contains the product of all elements to the left of 'nums[i]'.
4. Fill 'rightProducts' such that rightProducts[i] contains the product of all elements to the right of 'nums[i]'.
5. For each element in 'nums' at index i:
a. answer[i] = leftProducts[i] * rightProducts[i].
6. Return the 'answer' array.
Java Code for Optimized Solution
package codeKatha;
public class ProductOfArrayExceptSelf {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] leftProducts = new int[n];
int[] rightProducts = new int[n];
int[] answer = new int[n];
// Fill leftProducts
leftProducts[0] = 1;
for (int i = 1; i < n; i++) {
leftProducts[i] = nums[i - 1] * leftProducts[i - 1];
}
// Fill rightProducts
rightProducts[n - 1] = 1;
for (int i = n - 2; i >= 0; i--) {
rightProducts[i] = nums[i + 1] * rightProducts[i + 1];
}
// Fill answer
for (int i = 0; i < n; i++) {
answer[i] = leftProducts[i] * rightProducts[i];
}
return answer;
}
}
Dry Run
Let's dry run the optimized solution with an example:
Input: nums = [1, 2, 3, 4]
Step 1: Initialize leftProducts = [1, 1, 1, 1] Step 2: Initialize rightProducts = [1, 1, 1, 1] Step 3: Initialize answer = [1, 1, 1, 1] Step 4: Fill leftProducts: - leftProducts[1] = 1 * 1 = 1 - leftProducts[2] = 2 * 1 = 2 - leftProducts[3] = 3 * 2 = 6 leftProducts = [1, 1, 2, 6] Step 5: Fill rightProducts: - rightProducts[2] = 4 * 1 = 4 - rightProducts[1] = 3 * 4 = 12 - rightProducts[0] = 2 * 12 = 24 rightProducts = [24, 12, 4, 1] Step 6: Fill answer: - answer[0] = 1 * 24 = 24 - answer[1] = 1 * 12 = 12 - answer[2] = 2 * 4 = 8 - answer[3] = 6 * 1 = 6 Step 7: Return answer = [24, 12, 8, 6]
Time and Space Complexity
Time Complexity: O(n)
- We are iterating through the array three times, which is linear.
Space Complexity: O(n)
- We are using two extra arrays to store the left and right products.
More Optimized Solution
We can further optimize the solution by using the output array itself to store the left products, and we can calculate the right products on the fly.
Algorithm/Pseudocode
// More Optimized Approach
1. Initialize an array 'answer' of the same length as 'nums' and fill it with 1.
2. Fill 'answer' such that answer[i] contains the product of all elements to the left of 'nums[i]'.
3. Initialize a variable 'rightProduct' to 1.
4. Traverse the array from right to left and update 'answer' such that it contains the product of all elements except 'nums[i]'.
5. Return the 'answer' array.
Java Code for More Optimized Solution
package codeKatha;
public class ProductOfArrayExceptSelf {
public int[] productExceptSelf(int[] nums) {
int n = nums.length;
int[] answer = new int[n];
// Fill answer with left products
answer[0] = 1;
for (int i = 1; i < n; i++) {
answer[i] = nums[i - 1] * answer[i - 1];
}
// Calculate right products on the fly and update answer
int rightProduct = 1;
for (int i = n - 1; i >= 0; i--) {
answer[i] *= rightProduct;
rightProduct *= nums[i];
}
return answer;
}
}
Dry Run
Let's dry run the more optimized solution with an example:
Input: nums = [1, 2, 3, 4]
Step 1: Initialize answer = [1, 1, 1, 1] Step 2: Fill answer with left products: - answer[1] = 1 * 1 = 1 - answer[2] = 2 * 1 = 2 - answer[3] = 3 * 2 = 6 answer = [1, 1, 2, 6] Step 3: Initialize rightProduct = 1 Step 4: Traverse from right to left and update answer: - i = 3: answer[3] *= 1 => answer[3] = 6 rightProduct *= 4 => rightProduct = 4 - i = 2: answer[2] *= 4 => answer[2] = 8 rightProduct *= 3 => rightProduct = 12 - i = 1: answer[1] *= 12 => answer[1] = 12 rightProduct *= 2 => rightProduct = 24 - i = 0: answer[0] *= 24 => answer[0] = 24 rightProduct *= 1 => rightProduct = 24 Step 5: Return answer = [24, 12, 8, 6]
Time and Space Complexity
Time Complexity: O(n)
- We are iterating through the array three times, which is linear.
Space Complexity: O(1)
- We are using the output array itself to store the left products and calculating the right products on the fly.
Edge Cases
1. If the input array contains only one element, the output should be an empty array or an array with a single element 1 because there are no other elements to multiply.
2. If the input array contains zero, the product for the indices other than the zero index will be zero unless there is more than one zero.
By understanding these solutions, even a novice can grasp the concepts and apply the optimal approach for solving the "Product of Array Except Self" problem efficiently.
Comments
Post a Comment