Skip to content

Commit

Permalink
dsa
Browse files Browse the repository at this point in the history
- (leetcode) product of array except self
- prefix sum
  • Loading branch information
xy-241 committed Jun 1, 2024
1 parent 2d897f1 commit a3d4fb4
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 93 deletions.
8 changes: 4 additions & 4 deletions content/Algorithm/Prefix Sum (前缀和).md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Author Profile:
tags:
- dsa
Creation Date: 2023-10-08T19:28:00
Last Date: 2024-05-31T14:37:50+08:00
Last Date: 2024-06-01T13:20:47+08:00
---
## Abstract
---
Expand All @@ -15,7 +15,7 @@ Last Date: 2024-05-31T14:37:50+08:00

- Prefix sum is an [[Array]] that has the **same length** as a **given array**
- The **value at each index** is the **sum** of values from the **first element of the given array** to the **element at the current index**
- Calculates the **sum of a particular range** of a **given array** efficiently by leveraging on [[Memoization]]
- [[#Range Sum Query]] enables us to calculates the **sum of a particular range** of a **given array** efficiently by leveraging on [[Memoization]]

## Range Sum Query
---
Expand All @@ -28,12 +28,12 @@ Last Date: 2024-05-31T14:37:50+08:00


>[!tip]
>$Range[0, j]$ is **same** as $P_j$. So we can just retrieve the value from the prefix sum array with index $j$, instead of using the formula stated in the diagram above, which requires us to have a placeholder at index $0$.
>$Range[0, j]$ is **same** as $P_j$. So we can just retrieve the value from the **prefix sum array** with index $j$, instead of using the formula stated in the diagram above, which requires us to have a placeholder at index $0$.


## Practice Questions
---
- [ ] [[Product of Array Except Self]]
- [ ] [[Leetcode - Product of Array Except Self]]
- [ ] [[Romantic Glasses]]
- [ ] [[Closest Cities]]
118 changes: 118 additions & 0 deletions content/cp/prefix_sum/Leetcode - Product of Array Except Self.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
sthNew: true
Mastery Level:
- 📘
Time Taken: 15
Space:
- O(1)
Time: O(n)
Appears On:
- Grind 75
Brush: 5
Difficulty:
- Medium
Area:
- prefix_sum
- dynamic_programming
Reference 1: https://leetcode-solution-leetcode-pp.gitbook.io/leetcode-solution/medium/238.product-of-array-except-self
Reference 2:
Author:
- Xinyang YU
Author Profile:
- https://linkedin.com/in/xinyang-yu
Creation Date: 2024-01-08, 12:52
Last Date: 2024-06-01T15:10:38+08:00
tags:
- cp
draft:
description: Leetcode 238. Product of Array Except Self, detailed solution with hand-crafted visual
---

## Abstract
---
- [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) gives us an [[Array]], and we need to produce a new array with the same length, the elements inside the new array is the product of all the elements in the given array, excluding the element at the same index
- The solution must run in `O(n)`
- Can't use division operation
- The new array does not count as extra space for [[Algorithm Complexity Analysis#Worst Space Complexity]]
- We can make use of the idea presented in [[Prefix Sum (前缀和)]], **storing** the **intermediate product** to **avoid duplicated computation**. This allows us to obtain the answer in $O(n)$ time

## Solution
---

![[product_of_array_except_self.svg|600]]

- We can make use of the idea presented in [[Prefix Sum (前缀和)]], **storing** the **intermediate product** to **avoid duplicated computation** as shown in the diagram above. This allows us to obtain the answer in $O(n)$ time
- The element at a **particular index of the new array** is the **product** of **all elements at the left side** of that particular index and **all element at the right side** of that particular index. So we have **prefix product array** that keeps track of the **product of all elements at the left side** for all indexes, and **suffix product array** that keeps track of the **product of all elements at the right side** for all indexes. Then the answer is just the product of the **intermediate product** from **prefix product array** and **suffix product array**
- Below is the code implementation with Java based idea described above. From `prefix[i] = prefix[i - 1] * nums[i - 1]` and `suffix[i] = suffix[i + 1] * nums[i + 1]`, we can see we are making use of [[Dynamic Programming#Optimal Substructure (最优子结构)]] to avoid [[Dynamic Programming#Overlapping Subproblems (重复子问题)]]. We are able to use [[Dynamic Programming#Top-down DP Approach]] to create the **prefix product array** and **suffix product array**. `prefix[0] = 1` and `suffix[nums.length - 1] = 1` are the base case

```java
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] prefix = new int[nums.length];
int[] suffix = new int[nums.length];
int[] res = new int[nums.length];

prefix[0] = 1;
suffix[nums.length - 1] = 1;

for (int i = 1; i < nums.length; i++) {
prefix[i] = prefix[i - 1] * nums[i - 1];
}

for (int i = nums.length - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] * nums[i + 1];
}

for (int i = 0; i < nums.length; i++) {
res[i] = prefix[i] * suffix[i];
}

return res;
}
}
```

- We can further optimise the solution by replacing the **suffix product array** with **a variable** `suffix` as shown below. We are using `res` to produce the **prefix product array**, then compute the final answer array with the `suffix` variable, the **final product** at a **particular index** just needs the **suffix at that particular index**, **optimal substructure**

```java
class Solution {
public int[] productExceptSelf(int[] nums) {
int[] res = new int[nums.length];
res[0] = 1;

for (int i = 1; i < nums.length; i++) {
res[i] = res[i - 1] * nums[i - 1];
}

int suffix = 1;
for (int i = nums.length - 2; i >= 0; i--) {
suffix *= nums[i + 1];
res[i] = res[i] * suffix;
}

return res;
}
}
```



## Space & Time Analysis
---
The analysis method we are using is [[Algorithm Complexity Analysis]]
### Space - O(1)
- *Ignore input size & language dependent space*
- The output array isn't counted as stated by the question
### Time - O(n)
- We need to loop through the elements of the given array 2 times
- 1 time to obtain the **prefix product array**, another time to calculate the suffix to obtain the final answer


## Personal Reflection
---
- **Why it takes so long to solve:** Didn't read the problem carefully and implementing [[Prefix Sum (前缀和)]] on products of elements
- **What you could have done better:** Sketch out the calculation process clearly on the paper
- **What you missed:** *NIL*
- **Ideas you've seen before:** Prefix Sum (前缀和)
- **Ideas you found here that could help you later:** Prefix Sum (前缀和)'s ability to provide the product of a range of elements in O(1)
- **Ideas that didn't work and why:** *NIL*
89 changes: 0 additions & 89 deletions content/cp/prefix_sum/Product of Array Except Self.md

This file was deleted.

Binary file not shown.
8 changes: 8 additions & 0 deletions content/cp/prefix_sum/assets/product_of_array_except_self.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a3d4fb4

Please sign in to comment.