vault backup: 2022-09-05 14:48:29
This commit is contained in:
parent
5d97fd5b35
commit
294c59220e
155
OJ notes/pages/Leetcode Product-of-Array-Except-Self.md
Normal file
155
OJ notes/pages/Leetcode Product-of-Array-Except-Self.md
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
- [Link to problem](https://leetcode.com/problems/product-of-array-except-self/)
|
||||||
|
- [Solution with explanation](https://leetcode.com/problems/product-of-array-except-self/discuss/1597994/C%2B%2BPython-4-Simple-Solutions-w-Explanation-or-Prefix-and-Suffix-product-O(1)-space-approach)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
Second version:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
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:
|
||||||
|
```cpp
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
Loading…
Reference in a new issue