vault backup: 2022-09-05 14:48:29

This commit is contained in:
juan 2022-09-05 14:48:29 +08:00
parent 5d97fd5b35
commit 294c59220e

View 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;
}
};
```