https://leetcode.com/problems/product-of-array-except-self/
## タグ
## 概要
> 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.
## 方針
### Intuition
それぞれのindexに対して左側と右側の積を求めておけば、自身を除く積は左側と右側の積になる。
### Brute Force
Time Complexity: $O(n^2)$
単純に毎回自分以外の要素を掛ける。課題要件で$O(n)$が指定されているので使えない。
### すべての積を求めて自身の値で割る
課題要件として禁止されている。0が存在するとうまくいかない。
### 左側と右側の積を求める
Time Complexity: $O(n)$
Space Complexity: $O(n)$
Where: `n = len(nums)`
```python
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
left = [1] * n
right = [1] * n
for i in range(n):
if i != n - 1:
left[i + 1] = left[i] * nums[i]
right[n - i - 2] = right[n - i - 1] * nums[n - i - 1]
ans = [0] * n
for i in range(n):
ans[i] = left[i] * right[i]
return ans
```
### 左側と右側の積を求める(改良版)
Time Complexity: $O(n)$
Space Complexity: $O(1)$
Where: `n = len(nums)`
左側の積と右側の積をそれぞれ配列で持たせるのではなく、ansの配列だけでやる。
```python
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
ans = [1] * n
left = 1
right = 1
for i in range(n):
ans[i] *= left
ans[n - i - 1] *= right
left *= nums[i]
right *= nums[n - i - 1]
return ans
```
```python
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
ans = [1] * n
prefix_left_product = 1
for i in range(n):
ans[i] *= prefix_left_product
prefix_left_product *= nums[i]
prefix_right_product = 1
for i in range(n - 1, -1, -1):
ans[i] *= prefix_right_product
prefix_right_product *= nums[i]
return ans
```