Skip to content

Commit e13866d

Browse files
authored
feat: add solutions to lc problems (doocs#2029)
1 parent f5d3f05 commit e13866d

File tree

116 files changed

+1510
-391
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+1510
-391
lines changed

solution/0100-0199/0117.Populating Next Right Pointers in Each Node II/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is
6161

6262
**Solution 2: Space Optimization**
6363

64-
The space complexity of Method 1 is relatively high because it requires a queue to store the nodes of each level. We can implement it with constant space.
64+
The space complexity of Solution 1 is relatively high because it requires a queue to store the nodes of each level. We can implement it with constant space.
6565

6666
We define two pointers $prev$ and $next$, which point to the previous node and the first node of the next level, respectively. When traversing the nodes of the current level, we string the nodes of the next level together and find the first node of the next level. After the current level is traversed, we assign the first node $next$ of the next level to $node$ and continue to traverse.
6767

solution/0200-0299/0207.Course Schedule/README_EN.md

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ To take course 1 you should have finished course 0, and to take course 0 you sho
4444

4545
## Solutions
4646

47+
**Solution 1: Topological Sorting**
48+
49+
For this problem, we can consider the courses as nodes in a graph, and prerequisites as edges in the graph. Thus, we can transform this problem into determining whether there is a cycle in the directed graph.
50+
51+
Specifically, we can use the idea of topological sorting. For each node with an in-degree of $0$, we reduce the in-degree of its out-degree nodes by $1$, until all nodes have been traversed.
52+
53+
If all nodes have been traversed, it means there is no cycle in the graph, and we can complete all courses; otherwise, we cannot complete all courses.
54+
55+
The time complexity is $O(n + m)$, and the space complexity is $O(n + m)$. Here, $n$ and $m$ are the number of courses and prerequisites respectively.
56+
4757
<!-- tabs:start -->
4858

4959
### **Python3**

solution/0200-0299/0209.Minimum Size Subarray Sum/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070

7171
我们可以使用双指针 $j$ 和 $i$ 维护一个窗口,其中窗口中的所有元素之和小于 $target$。初始时 $j = 0$,答案 $ans = n + 1$,其中 $n$ 为数组 $nums$ 的长度。
7272

73-
接下来,指针 $i$ 从 $0$ 开始向右移动,每次移动一步,我们将指针 $i$ 对应的元素加入窗口,同时更新窗口中元素之和。如果窗口中元素之和大于等于 $target$,说明当前子数组满足条件,我们可以更新答案,即 $ans = min(ans, i - j + 1)$。然后我们不断地从窗口中移除元素 $nums[j]$,直到窗口中元素之和小于 $target$,然后重复上述过程。
73+
接下来,指针 $i$ 从 $0$ 开始向右移动,每次移动一步,我们将指针 $i$ 对应的元素加入窗口,同时更新窗口中元素之和。如果窗口中元素之和大于等于 $target$,说明当前子数组满足条件,我们可以更新答案,即 $ans = \min(ans, i - j + 1)$。然后我们不断地从窗口中移除元素 $nums[j]$,直到窗口中元素之和小于 $target$,然后重复上述过程。
7474

7575
最后,如果 $ans \leq n$,则说明存在满足条件的子数组,返回 $ans$,否则返回 $0$。
7676

solution/0200-0299/0209.Minimum Size Subarray Sum/README_EN.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,25 @@
4343

4444
## Solutions
4545

46-
**Method 1: PreSum & Binary search**
46+
**Solution 1: Prefix Sum + Binary Search**
4747

48-
**Method 2: Slide window**
48+
First, we preprocess the prefix sum array $s$ of the array $nums$, where $s[i]$ represents the sum of the first $i$ elements of the array $nums$. Since all elements in the array $nums$ are positive integers, the array $s$ is also monotonically increasing. Also, we initialize the answer $ans = n + 1$, where $n$ is the length of the array $nums$.
49+
50+
Next, we traverse the prefix sum array $s$. For each element $s[i]$, we can find the smallest index $j$ that satisfies $s[j] \geq s[i] + target$ by binary search. If $j \leq n$, it means that there exists a subarray that satisfies the condition, and we can update the answer, i.e., $ans = min(ans, j - i)$.
51+
52+
Finally, if $ans \leq n$, it means that there exists a subarray that satisfies the condition, return $ans$, otherwise return $0$.
53+
54+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $nums$.
55+
56+
**Solution 2: Two Pointers**
57+
58+
We can use two pointers $j$ and $i$ to maintain a window, where the sum of all elements in the window is less than $target$. Initially, $j = 0$, and the answer $ans = n + 1$, where $n$ is the length of the array $nums$.
59+
60+
Next, the pointer $i$ starts to move to the right from $0$, moving one step each time. We add the element corresponding to the pointer $i$ to the window and update the sum of the elements in the window. If the sum of the elements in the window is greater than or equal to $target$, it means that the current subarray satisfies the condition, and we can update the answer, i.e., $ans = \min(ans, i - j + 1)$. Then we continuously remove the element $nums[j]$ from the window until the sum of the elements in the window is less than $target$, and then repeat the above process.
61+
62+
Finally, if $ans \leq n$, it means that there exists a subarray that satisfies the condition, return $ans$, otherwise return $0$.
63+
64+
The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array $nums$.
4965

5066
<!-- tabs:start -->
5167

solution/0300-0399/0367.Valid Perfect Square/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636

3737
## Solutions
3838

39-
**Method 1: Binary search**
39+
**Solution 1: Binary search**
4040

41-
**Method 2: Math trick**
41+
**Solution 2: Math trick**
4242

4343
This is a math problem:
4444

solution/0600-0699/0619.Biggest Single Number/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ We can first group the `MyNumbers` table by `num` and count the number of occurr
8585

8686
**Solution 2: Grouping and `CASE` Expression**
8787

88-
Similar to Method 1, we can first group the `MyNumbers` table by `num` and count the number of occurrences of each number. Then, we can use a `CASE` expression to find the numbers that appear only once, sort them in descending order by number, and take the first one.
88+
Similar to Solution 1, we can first group the `MyNumbers` table by `num` and count the number of occurrences of each number. Then, we can use a `CASE` expression to find the numbers that appear only once, sort them in descending order by number, and take the first one.
8989

9090
<!-- tabs:start -->
9191

solution/0600-0699/0658.Find K Closest Elements/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333

3434
## Solutions
3535

36-
**Method 1: Sort**
36+
**Solution 1: Sort**
3737

38-
**Method 2: Binary search**
38+
**Solution 2: Binary search**
3939

4040
<!-- tabs:start -->
4141

solution/1000-1099/1099.Two Sum Less Than K/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log
4646

4747
**Solution 2: Sorting + Two Pointers**
4848

49-
Similar to Method 1, we can first sort the array $nums$, and initialize the answer as $-1$.
49+
Similar to Solution 1, we can first sort the array $nums$, and initialize the answer as $-1$.
5050

5151
Next, we use two pointers $i$ and $j$ to point to the left and right ends of the array, respectively. Each time we judge whether $s = nums[i] + nums[j]$ is less than $k$. If it is less than $k$, then we can update the answer, i.e., $ans = \max(ans, s)$, and move $i$ one step to the right, otherwise move $j$ one step to the left.
5252

solution/1100-1199/1123.Lowest Common Ancestor of Deepest Leaves/README_EN.md

+11
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,17 @@ Note that nodes 6, 0, and 8 are also leaf nodes, but the depth of them is 2, but
5454

5555
## Solutions
5656

57+
**Solution 1: DFS**
58+
59+
We design a function `dfs(root)` that returns a tuple `(l, d)`, where `l` is the deepest common ancestor of node `root`, and `d` is the depth of node `root`. The execution logic of the function `dfs(root)` is as follows:
60+
61+
- If `root` is null, return the tuple `(None, 0)`;
62+
- Otherwise, we recursively call `dfs(root.left)` and `dfs(root.right)`, obtaining tuples `(l, d1)` and `(r, d2)`. If `d1 > d2`, the deepest common ancestor of `root` is `l`, and the depth is `d1 + 1`; if `d1 < d2`, the deepest common ancestor of `root` is `r`, and the depth is `d2 + 1`; if `d1 = d2`, the deepest common ancestor of `root` is `root`, and the depth is `d1 + 1`.
63+
64+
In the main function, we call `dfs(root)` and return the first element of its return value to get the deepest common ancestor node.
65+
66+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
67+
5768
<!-- tabs:start -->
5869

5970
### **Python3**

solution/1100-1199/1124.Longest Well-Performing Interval/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
接下来,我们遍历数组 `hours`,对于每个下标 $i$:
5151

5252
- 如果 $hours[i] \gt 8$,我们就让 $s$ 加 $1$,否则减 $1$。
53-
- 如果 $s$ 大于 $0$,说明从下标 $0$ 到当前下标的这一段,满足「表现良好的时间段」,我们更新结果 $ans = i + 1$。否则,如果 $s - 1$ 在哈希表 $pos$ 中,记 $j = pos[s - 1]$,说明从下标 $j + 1$ 到当前下标 $i$ 的这一段,满足「表现良好的时间段」,我们更新结果 $ans = max(ans, i - j)$。
53+
- 如果 $s$ 大于 $0$,说明从下标 $0$ 到当前下标的这一段,满足「表现良好的时间段」,我们更新结果 $ans = i + 1$。否则,如果 $s - 1$ 在哈希表 $pos$ 中,记 $j = pos[s - 1]$,说明从下标 $j + 1$ 到当前下标 $i$ 的这一段,满足「表现良好的时间段」,我们更新结果 $ans = \max(ans, i - j)$。
5454
- 然后,如果 $s$ 不在哈希表 $pos$ 中,我们就记录 $pos[s] = i$。
5555

5656
遍历结束后,返回答案即可。

solution/1100-1199/1124.Longest Well-Performing Interval/README_EN.md

+14
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@
3838

3939
## Solutions
4040

41+
**Solution 1: Prefix Sum + Hash Table**
42+
43+
We can use the idea of prefix sum, maintaining a variable $s$, which represents the difference between the number of "tiring days" and "non-tiring days" from index $0$ to the current index. If $s$ is greater than $0$, it means that the segment from index $0$ to the current index is a "well-performing time period". In addition, we use a hash table $pos$ to record the first occurrence index of each $s$.
44+
45+
Next, we traverse the `hours` array, for each index $i$:
46+
47+
- If $hours[i] > 8$, we increment $s$ by $1$, otherwise we decrement $s$ by $1$.
48+
- If $s > 0$, it means that the segment from index $0$ to the current index $i$ is a "well-performing time period", we update the result $ans = i + 1$. Otherwise, if $s - 1$ is in the hash table $pos$, let $j = pos[s - 1]$, it means that the segment from index $j + 1$ to the current index $i$ is a "well-performing time period", we update the result $ans = \max(ans, i - j)$.
49+
- Then, if $s$ is not in the hash table $pos$, we record $pos[s] = i$.
50+
51+
After the traversal, return the answer.
52+
53+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the `hours` array.
54+
4155
<!-- tabs:start -->
4256

4357
### **Python3**

solution/1100-1199/1125.Smallest Sufficient Team/README_EN.md

+20
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@
4343

4444
## Solutions
4545

46+
**Solution 1: State Compression Dynamic Programming**
47+
48+
We notice that the length of `req_skills` does not exceed $16$, so we can use a binary number of length no more than $16$ to represent whether each skill is mastered. Let's denote the length of `req_skills` as $m$ and the length of `people` as $n$.
49+
50+
First, we map each skill in `req_skills` to a number, i.e., $d[s]$ represents the number of skill $s$. Then, we traverse each person in `people` and represent the skills they master with a binary number, i.e., $p[i]$ represents the skills mastered by the person with number $i$.
51+
52+
Next, we define the following three arrays:
53+
54+
- Array $f[i]$ represents the minimum number of people to master the skill set $i$, where each bit of the binary representation of $i$ is $1$, indicating that the corresponding skill is mastered. Initially, $f[0] = 0$, and all other positions are infinity.
55+
- Array $g[i]$ represents the number of the last person when the skill set $i$ is mastered by the minimum number of people.
56+
- Array $h[i]$ represents the previous skill set state when the skill set $i$ is mastered by the minimum number of people.
57+
58+
We enumerate each skill set in the range of $[0,..2^m-1]$, for each skill set $i$:
59+
60+
We enumerate each person $j$ in `people`. If $f[i] + 1 \lt f[i | p[j]]$, it means that $f[i | p[j]]$ can be transferred from $f[i]$. At this time, we update $f[i | p[j]]$ to $f[i] + 1$, and update $g[i | p[j]]$ to $j$, and update $h[i | p[j]]$ to $i$. That is, when the current skill set state is $i | p[j]$, the number of the last person is $j$, and the previous skill set state is $i$. Here, the symbol $|$ represents bitwise OR operation.
61+
62+
Finally, we start from the skill set $i=2^m-1$, find the number of the last person at this time $g[i]$, add it to the answer, then update $i$ to $h[i]$, and keep backtracking until $i=0$, to get the personnel numbers in the smallest necessary team.
63+
64+
The time complexity is $O(2^m \times n)$, and the space complexity is $O(2^m)$. Here, $m$ and $n$ are the lengths of `req_skills` and `people`, respectively.
65+
4666
<!-- tabs:start -->
4767

4868
### **Python3**

solution/1100-1199/1128.Number of Equivalent Domino Pairs/README_EN.md

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434

3535
## Solutions
3636

37+
**Solution 1: Counting**
38+
39+
We can concatenate the two numbers of each domino in order of size to form a two-digit number, so that equivalent dominoes can be concatenated into the same two-digit number. For example, both `[1, 2]` and `[2, 1]` are concatenated into the two-digit number `12`, and both `[3, 4]` and `[4, 3]` are concatenated into the two-digit number `34`.
40+
41+
Then we traverse all the dominoes, using an array $cnt$ of length $100$ to record the number of occurrences of each two-digit number. For each domino, the two-digit number we concatenate is $x$, then the answer will increase by $cnt[x]$, and then we add $1$ to the value of $cnt[x]$. Continue to traverse the next domino, and we can count the number of all equivalent domino pairs.
42+
43+
The time complexity is $O(n)$, and the space complexity is $O(C)$. Here, $n$ is the number of dominoes, and $C$ is the maximum number of two-digit numbers concatenated in the dominoes, which is $100$.
44+
3745
<!-- tabs:start -->
3846

3947
### **Python3**

solution/1100-1199/1129.Shortest Path with Alternating Colors/README_EN.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,26 @@
4242

4343
## Solutions
4444

45-
BFS.
45+
**Solution 1: BFS**
46+
47+
The problem is essentially a shortest path problem, which we can consider solving using BFS.
48+
49+
First, we preprocess all the edges, categorizing all the edges by color and storing them in a multi-dimensional array $g$. Where $g[0]$ stores all red edges, and $g[1]$ stores all blue edges.
50+
51+
Next, we define the following data structures or variables:
52+
53+
- Queue $q$: used to store the currently searched node and the color of the current edge;
54+
- Set $vis$: used to store the nodes that have been searched and the color of the current edge;
55+
- Variable $d$: used to represent the current search level, i.e., the distance from the currently searched node to the starting point;
56+
- Array $ans$: used to store the shortest distance from each node to the starting point. Initially, we initialize all elements in the $ans$ array to $-1$, indicating that the distance from all nodes to the starting point is unknown.
57+
58+
We first enqueue the starting point $0$ and the color of the starting edge $0$ or $1$, indicating that we start from the starting point and the current edge is red or blue.
59+
60+
Next, we start the BFS search. Each time we take out a node $(i, c)$ from the queue, if the answer of the current node has not been updated, then we update the answer of the current node to the current level $d$, i.e., $ans[i] = d$. Then, we flip the color of the current edge $c$, i.e., if the current edge is red, we change it to blue, and vice versa. We take out all edges corresponding to the color, if the other end node $j$ of the edge has not been searched, then we enqueue it.
61+
62+
After the search is over, return the answer array.
63+
64+
The time complexity is $O(n + m)$, and the space complexity is $O(n + m)$. Here, $n$ and $m$ are the number of nodes and edges, respectively.
4665

4766
<!-- tabs:start -->
4867

solution/1100-1199/1130.Minimum Cost Tree From Leaf Values/README_EN.md

+50
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,56 @@ The first has a non-leaf node sum 36, and the second has non-leaf node sum 32.
4444

4545
## Solutions
4646

47+
**Solution 1: Memoization Search**
48+
49+
According to the problem description, the values in the array $arr$ correspond one-to-one with the values in the inorder traversal of each leaf node of the tree. We can divide the array into two non-empty sub-arrays, corresponding to the left and right subtrees of the tree, and recursively solve for the minimum possible sum of all non-leaf node values in each subtree.
50+
51+
We design a function $dfs(i, j)$, which represents the minimum possible sum of all non-leaf node values in the index range $[i, j]$ of the array $arr$. The answer is $dfs(0, n - 1)$, where $n$ is the length of the array $arr$.
52+
53+
The calculation process of the function $dfs(i, j)$ is as follows:
54+
55+
- If $i = j$, it means that there is only one element in the array $arr[i..j]$, and there are no non-leaf nodes, so $dfs(i, j) = 0$.
56+
- Otherwise, we enumerate $k \in [i, j - 1]$, divide the array $arr$ into two sub-arrays $arr[i..k]$ and $arr[k + 1..j]$. For each $k$, we recursively calculate $dfs(i, k)$ and $dfs(k + 1, j)$. Here, $dfs(i, k)$ represents the minimum possible sum of all non-leaf node values in the index range $[i, k]$ of the array $arr$, and $dfs(k + 1, j)$ represents the minimum possible sum of all non-leaf node values in the index range $[k + 1, j]$ of the array $arr$. So $dfs(i, j) = \min_{i \leq k < j} \{dfs(i, k) + dfs(k + 1, j) + \max_{i \leq t \leq k} \{arr[t]\} \max_{k < t \leq j} \{arr[t]\}\}$.
57+
58+
In summary, we can get:
59+
60+
$$
61+
dfs(i, j) = \begin{cases}
62+
0, & \text{if } i = j \\
63+
\min_{i \leq k < j} \{dfs(i, k) + dfs(k + 1, j) + \max_{i \leq t \leq k} \{arr[t]\} \max_{k < t \leq j} \{arr[t]\}\}, & \text{if } i < j
64+
\end{cases}
65+
$$
66+
67+
In the above recursive process, we can use the method of memoization search to avoid repeated calculations. Additionally, we can use an array $g$ to record the maximum value of all leaf nodes in the index range $[i, j]$ of the array $arr$. This allows us to optimize the calculation process of $dfs(i, j)$:
68+
69+
$$
70+
dfs(i, j) = \begin{cases}
71+
0, & \text{if } i = j \\
72+
\min_{i \leq k < j} \{dfs(i, k) + dfs(k + 1, j) + g[i][k] \cdot g[k + 1][j]\}, & \text{if } i < j
73+
\end{cases}
74+
$$
75+
76+
Finally, we return $dfs(0, n - 1)$.
77+
78+
The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array $arr$.
79+
80+
**Solution 2: Dynamic Programming**
81+
82+
We can change the memoization search in Solution 1 to dynamic programming.
83+
84+
Define $f[i][j]$ to represent the minimum possible sum of all non-leaf node values in the index range $[i, j]$ of the array $arr$, and $g[i][j]$ to represent the maximum value of all leaf nodes in the index range $[i, j]$ of the array $arr$. Then, the state transition equation is:
85+
86+
$$
87+
f[i][j] = \begin{cases}
88+
0, & \text{if } i = j \\
89+
\min_{i \leq k < j} \{f[i][k] + f[k + 1][j] + g[i][k] \cdot g[k + 1][j]\}, & \text{if } i < j
90+
\end{cases}
91+
$$
92+
93+
Finally, we return $f[0][n - 1]$.
94+
95+
The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array $arr$.
96+
4797
<!-- tabs:start -->
4898

4999
### **Python3**

solution/1100-1199/1131.Maximum of Absolute Value Expression/README_EN.md

+17
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@
3535

3636
## Solutions
3737

38+
**Solution 1: Mathematics + Enumeration**
39+
40+
Let's denote $x_i = arr1[i]$, $y_i = arr2[i]$. Since the size relationship between $i$ and $j$ does not affect the value of the expression, we can assume $i \ge j$. Then the expression can be transformed into:
41+
42+
$$
43+
| x_i - x_j | + | y_i - y_j | + i - j = \max \begin{cases} (x_i + y_i) - (x_j + y_j) \\ (x_i - y_i) - (x_j - y_j) \\ (-x_i + y_i) - (-x_j + y_j) \\ (-x_i - y_i) - (-x_j - y_j) \end{cases} + i - j\\
44+
= \max \begin{cases} (x_i + y_i + i) - (x_j + y_j + j) \\ (x_i - y_i + i) - (x_j - y_j + j) \\ (-x_i + y_i + i) - (-x_j + y_j + j) \\ (-x_i - y_i + i) - (-x_j - y_j + j) \end{cases}
45+
$$
46+
47+
Therefore, we just need to find the maximum value $mx$ and the minimum value $mi$ of $a \times x_i + b \times y_i + i$, where $a, b \in \{-1, 1\}$. The answer is the maximum value among all $mx - mi$.
48+
49+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
50+
51+
Similar problems:
52+
53+
- [1330. Reverse Subarray To Maximize Array Value](/solution/1300-1399/1330.Reverse%20Subarray%20To%20Maximize%20Array%20Value/README_EN.md)
54+
3855
<!-- tabs:start -->
3956

4057
### **Python3**

solution/1100-1199/1133.Largest Unique Number/README_EN.md

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232

3333
## Solutions
3434

35+
**Solution 1: Counting + Reverse Traversal**
36+
37+
Given the data range in the problem, we can use an array of length $1001$ to count the occurrence of each number. Then, we traverse the array in reverse order to find the first number that appears only once. If no such number is found, we return $-1$.
38+
39+
The time complexity is $O(n + M)$, and the space complexity is $O(M)$. Here, $n$ is the length of the array, and $M$ is the maximum number that appears in the array. In this problem, $M \leq 1000$.
40+
3541
<!-- tabs:start -->
3642

3743
### **Python3**

0 commit comments

Comments
 (0)