Given an integer array nums, return an array answer where answer[index] equals the product of every element in nums except nums[index].
The product must be calculated without using the value at the current index.
Return an empty array when nums is empty.
Example 1
Input: nums = [1, 2, 3, 4]
Output: [24, 12, 8, 6]
Explanation: For each index, we multiply all elements except the current element. For index 0, product is 2 × 3 × 4 = 24.
Example 2
Input: nums = [-1, 1, 0, -3, 3]
Output: [0, 0, 9, 0, 0]
Explanation: Only the index containing 0 gets the product of all non-zero elements. Other positions become 0 because their product includes 0.
Brute Force Approach
The most direct idea processes every index separately.
For each position, every other array element is multiplied while the current position is skipped. This follows the problem definition exactly, but the same values are multiplied repeatedly for different indices.
Algorithm
Store the array size in
n. Ifn == 0, return an empty array because there is no index for which a product can be calculated.Create an
answerarray of sizen, whereanswer[index]will store the product of all elements exceptnums[index].Treat every index
excludedIndexas the position that must be excluded from the current product.Initialize
productwith1for eachexcludedIndex, since1is the multiplicative identity and does not affect the product.Traverse the complete array and multiply
productbynums[currentIndex]only whencurrentIndex != excludedIndex. After all other elements have been processed, store the completed product inanswer[excludedIndex].Return
answerafter the product for every index has been calculated.
Dry Run
Product of Array Except Itself Brute Force Approach.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: vector<long long> productExceptSelf(vector<int>& nums) { int n = nums.size(); if (n == 0) { return {}; } vector<long long> answer(n); for (int excludedIndex = 0; excludedIndex < n; excludedIndex++) { long long product = 1; /* * Multiply every element except * the value at excludedIndex. */ for (int currentIndex = 0; currentIndex < n; currentIndex++) { if (currentIndex != excludedIndex) { product *= nums[currentIndex]; } } answer[excludedIndex] = product; } return answer; }};int main() { vector<int> nums = {1, 2, 3, 4}; Solution solution; vector<long long> answer = solution.productExceptSelf(nums); for (long long value : answer) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O(N²), where N represents the array size. Every index requires another complete traversal of the array.
Space Complexity: O(N) for the output array. No additional data structure is required apart from the returned result.
Better Approach
The product except the current element can be divided into two independent parts:
Product of all elements before the current index.
Product of all elements after the current index.
Storing both products in prefix and suffix arrays removes the need to multiply the complete array again for every position.
Algorithm
Store the array size in
n. If the array is empty, return an empty array.Create
prefix,suffix, andanswerarrays of sizen. Here,prefix[index]stores the product of elements beforeindex, whilesuffix[index]stores the product of elements after it.Set
prefix[0] = 1because no element exists before the first index. Build the remaining values usingprefix[index] = prefix[index - 1] × nums[index - 1].Set
suffix[n - 1] = 1because no element exists after the last index. Traverse from right to left and build each value usingsuffix[index] = suffix[index + 1] × nums[index + 1].For every index, multiply
prefix[index]andsuffix[index]. Their product contains every array element except the value at the current position.Store the result in
answer[index]and return the completedanswerarray.
Dry Run
Product of Array Except Itself Better Force Approach.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: vector<long long> productExceptSelf(vector<int>& nums) { int n = nums.size(); if (n == 0) { return {}; } vector<long long> prefix(n); vector<long long> suffix(n); vector<long long> answer(n); // No element exists before index 0. prefix[0] = 1; for (int index = 1; index < n; index++) { prefix[index] = prefix[index - 1] * nums[index - 1]; } // No element exists after the last index. suffix[n - 1] = 1; for (int index = n - 2; index >= 0; index--) { suffix[index] = suffix[index + 1] * nums[index + 1]; } /* * Combining both sides excludes * the value at the current index. */ for (int index = 0; index < n; index++) { answer[index] = prefix[index] * suffix[index]; } return answer; }};int main() { vector<int> nums = {1, 2, 3, 4}; Solution solution; vector<long long> answer = solution.productExceptSelf(nums); for (long long value : answer) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the array size. Linear traversals build the prefix products, suffix products, and final result.
Space Complexity: O(N) auxiliary space for the prefix and suffix arrays. The returned answer array also requires O(N) space.
Optimal Approach
Separate prefix and suffix arrays are not both necessary.
The output array can first store the product of every element on the left. A running product from the right can then complete each result by multiplying the already stored left product with the product of all elements on the right.
Algorithm
Store the array size in
n. Ifn == 0, return an empty array.Create an
answerarray of sizenand initializeleftProduct = 1. This variable stores the product of all elements appearing before the current index.Traverse from left to right. Store
leftProductinanswer[index]before multiplying it bynums[index], ensuring that the current value is excluded from its own result.Initialize
rightProduct = 1, where it represents the product of all elements appearing after the current index.Traverse from right to left. Multiply
answer[index]byrightProduct, then includenums[index]inrightProductso it becomes available for the next position to the left.Return
answerafter both traversals are complete.
Dry Run
Product of Array Except Itself Optimal Force Approach.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: vector<long long> productExceptSelf(vector<int>& nums) { int n = nums.size(); if (n == 0) { return {}; } vector<long long> answer(n); long long leftProduct = 1; /* * Store the product of all elements * appearing before each index. */ for (int index = 0; index < n; index++) { answer[index] = leftProduct; leftProduct *= nums[index]; } long long rightProduct = 1; /* * Multiply the stored left product * by the product of elements on the right. */ for (int index = n - 1; index >= 0; index--) { answer[index] *= rightProduct; rightProduct *= nums[index]; } return answer; }};int main() { vector<int> nums = {1, 2, 3, 4}; Solution solution; vector<long long> answer = solution.productExceptSelf(nums); for (long long value : answer) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the array size. One traversal stores the left products, and another traversal includes the right products.
Space Complexity: O(1) auxiliary space when the returned answer array is excluded. Only leftProduct and rightProduct require additional storage.
FAQs
Q1. Why are the missing prefix and suffix products represented by 1?
1 is the multiplicative identity. Multiplying by 1 leaves the available product unchanged, making boundary indices work without special calculations.
Q2. How does the approach handle one zero in the array?
Every result except the zero position becomes 0. The zero position receives the product of all non-zero elements.
Q3. What happens when the array contains more than one zero?
Every result becomes 0 because excluding any single index still leaves at least one zero in the remaining product.
Q4. Why is division usually avoided for this problem?
Division requires separate handling for zero values and may be disallowed by the problem constraints. Prefix and suffix products handle zero naturally.
Q5. What is returned when the array contains one element?
The result is [1]. After excluding the only element, no values remain, and the product of an empty collection is treated as 1.
Q6. What should be considered when array values are large?
Intermediate products may exceed the standard integer range. A wider numeric type should be used when the constraints allow large products.
Be the first to add a comment.