3.5 KiB
Leetcode Product-of-Array-Except-Self
2022-09-05 14:27
Algorithms:
#algorithm #prefix_sum
Data structures:
#DS
Difficulty:
#coding_problem #difficulty-medium
Additional tags:
#leetcode #CS_list_need_understanding
Revisions:
N/A
Links:
Problem
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.
Examples
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 <= 105
-30 <= nums[i] <= 30
- The product of any prefix or suffix of
nums
is guaranteed to fit in a 32-bit integer.
Thoughts
[!summary] This is a variation of #prefix_sum
I thought of using prefix product, a variation of prefix_sum, which perfectly fits the requirement.
First iteration:
keep two arrays: the suffix product and the prefix product
of the nums
array.
Then, ans = prefix[i] * suffix[i]
Second iteration:
It's like rolling snowball, the suffix sum variable gets reused
We can use only one output array:
write the prefix to the ans
array, and update it from
end using suffix sum variable.
This achieves the O(1) space except output
requirement.
Third iteration:
Since the multiplying process is independent, and can be reversed, We can do that in one loop.
1 * A * B == 1 * B * A
If we initialize the ans array as one, we can do that in one loop.
Solution
Third version:
class Solution {
public:
vector<int> productExceptSelf(vector<int> &nums) {
// Optimized one-pass prefix sum & suffix sum
int size = nums.size();
vector<int> ans(size, 1);
int prefix = 1, suffix = 1;
for (int i = 0; i < size; i++) {
ans[i] *= prefix;
prefix *= nums[i];
ans[size - i - 1] *= suffix;
suffix *= nums[size - i - 1];
}
return ans;
}
};
Second version:
class Solution {
public:
vector<int> productExceptSelf(vector<int> &nums) {
// Optimized prefix sum & suffix sum
int size = nums.size();
vector<int> ans(size);
ans[0] = 1;
for (int i = 1; i < size; i++) {
ans[i] = ans[i - 1] * nums[i - 1];
}
int suffix = 1;
for (int i = size - 1; i >= 0; i--) {
ans[i] = ans[i] * suffix;
suffix = suffix * nums[i];
}
return ans;
}
};
First iteration:
class Solution {
public:
vector<int> productExceptSelf(vector<int> &nums) {
// method 1: prefix sum & suffix sum
vector<int> ans;
vector<int> suffix;
int size = nums.size();
ans.resize(size);
suffix.resize(size);
ans[0] = 1;
for (int i = 1; i < size; i++) {
ans[i] = ans[i - 1] * nums[i - 1];
}
suffix[size - 1] = 1;
for (int i = size - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] * nums[i + 1];
}
for (int i = 0; i < size; i++) {
ans[i] = ans[i] * suffix[i];
}
return ans;
}
};