Skip to content

Commit 52f0f46

Browse files
authored
feat: add solutions to lc problems (#2031)
1 parent ce5aaa6 commit 52f0f46

File tree

90 files changed

+1110
-164
lines changed

Some content is hidden

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

90 files changed

+1110
-164
lines changed

solution/0000-0099/0039.Combination Sum/README_EN.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,25 @@ These are the only two combinations.
4848

4949
## Solutions
5050

51-
DFS.
51+
**Solution 1: Sorting + Pruning + Backtracking (Two Implementations)**
52+
53+
We can first sort the array to facilitate pruning.
54+
55+
Next, we design a function $dfs(i, s)$, which means starting the search from index $i$ with a remaining target value of $s$. Here, $i$ and $s$ are both non-negative integers, the current search path is $t$, and the answer is $ans$.
56+
57+
In the function $dfs(i, s)$, we first check whether $s$ is $0$. If it is, we add the current search path $t$ to the answer $ans$, and then return. If $s \lt candidates[i]$, it means that the elements of the current index and the following indices are all greater than the remaining target value $s$, and the path is invalid, so we return directly. Otherwise, we start the search from index $i$, and the search index range is $j \in [i, n)$, where $n$ is the length of the array $candidates$. During the search, we add the element of the current index to the search path $t$, recursively call the function $dfs(j, s - candidates[j])$, and after the recursion ends, we remove the element of the current index from the search path $t$.
58+
59+
We can also change the implementation logic of the function $dfs(i, s)$ to another form. In the function $dfs(i, s)$, we first check whether $s$ is $0$. If it is, we add the current search path $t$ to the answer $ans$, and then return. If $i \geq n$ or $s \lt candidates[i]$, the path is invalid, so we return directly. Otherwise, we consider two situations, one is not selecting the element of the current index, that is, recursively calling the function $dfs(i + 1, s)$, and the other is selecting the element of the current index, that is, recursively calling the function $dfs(i, s - candidates[i])$.
60+
61+
In the main function, we just need to call the function $dfs(0, target)$ to get the answer.
62+
63+
The time complexity is $O(2^n \times n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $candidates$. Due to pruning, the actual time complexity is much less than $O(2^n \times n)$.
64+
65+
Similar problems:
66+
67+
- [40. Combination Sum II](/solution/0000-0099/0040.Combination%20Sum%20II/README_EN.md)
68+
- [77. Combinations](/solution/0000-0099/0077.Combinations/README_EN.md)
69+
- [216. Combination Sum III](/solution/0200-0299/0216.Combination%20Sum%20III/README_EN.md)
5270

5371
<!-- tabs:start -->
5472

solution/0000-0099/0040.Combination Sum II/README_EN.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,25 @@
4646

4747
## Solutions
4848

49-
DFS.
49+
**Solution 1: Sorting + Pruning + Backtracking (Two Implementations)**
50+
51+
We can first sort the array to facilitate pruning and skipping duplicate numbers.
52+
53+
Next, we design a function $dfs(i, s)$, which means starting the search from index $i$ with a remaining target value of $s$. Here, $i$ and $s$ are both non-negative integers, the current search path is $t$, and the answer is $ans$.
54+
55+
In the function $dfs(i, s)$, we first check whether $s$ is $0$. If it is, we add the current search path $t$ to the answer $ans$, and then return. If $i \geq n$ or $s \lt candidates[i]$, the path is invalid, so we return directly. Otherwise, we start the search from index $i$, and the search index range is $j \in [i, n)$, where $n$ is the length of the array $candidates$. During the search, if $j \gt i$ and $candidates[j] = candidates[j - 1]$, it means that the current number is the same as the previous number, we can skip the current number because the previous number has been searched. Otherwise, we add the current number to the search path $t$, recursively call the function $dfs(j + 1, s - candidates[j])$, and after the recursion ends, we remove the current number from the search path $t$.
56+
57+
We can also change the implementation logic of the function $dfs(i, s)$ to another form. If we choose the current number, we add the current number to the search path $t$, then recursively call the function $dfs(i + 1, s - candidates[i])$, and after the recursion ends, we remove the current number from the search path $t$. If we do not choose the current number, we can skip all numbers that are the same as the current number, then recursively call the function $dfs(j, s)$, where $j$ is the index of the first number that is different from the current number.
58+
59+
In the main function, we just need to call the function $dfs(0, target)$ to get the answer.
60+
61+
The time complexity is $O(2^n \times n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array $candidates$. Due to pruning, the actual time complexity is much less than $O(2^n \times n)$.
62+
63+
Similar problems:
64+
65+
- [39. Combination Sum](/solution/0000-0099/0039.Combination%20Sum/README_EN.md)
66+
- [77. Combinations](/solution/0000-0099/0077.Combinations/README_EN.md)
67+
- [216. Combination Sum III](/solution/0200-0299/0216.Combination%20Sum%20III/README_EN.md)
5068

5169
<!-- tabs:start -->
5270

solution/0000-0099/0041.First Missing Positive/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@
4747

4848
**方法一:原地交换**
4949

50-
我们假设数组 `nums` 长度为 $n$,那么最小的正整数一定在 $[1, .., n + 1]$ 之间。我们可以遍历数组,将数组中的每个数 $x$ 交换到它应该在的位置上,即 $x$ 应该在的位置为 $x - 1$。如果 $x$ 不在 $[1, n + 1]$ 之间,那么我们就不用管它。
50+
我们假设数组 $nums$ 长度为 $n$,那么最小的正整数一定在 $[1, .., n + 1]$ 之间。我们可以遍历数组,将数组中的每个数 $x$ 交换到它应该在的位置上,即 $x$ 应该在的位置为 $x - 1$。如果 $x$ 不在 $[1, n + 1]$ 之间,那么我们就不用管它。
5151

5252
遍历结束后,我们再遍历数组,如果 $i+1$ 不等于 $nums[i]$,那么 $i+1$ 就是我们要找的最小的正整数。
5353

54-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
54+
时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。
5555

5656
<!-- tabs:start -->
5757

solution/0000-0099/0041.First Missing Positive/README_EN.md

+8
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@
4343

4444
## Solutions
4545

46+
**Solution 1: In-place Swap**
47+
48+
We assume the length of the array $nums$ is $n$, then the smallest positive integer must be in the range $[1, .., n + 1]$. We can traverse the array and swap each number $x$ to its correct position, that is, the position $x - 1$. If $x$ is not in the range $[1, n + 1]$, then we can ignore it.
49+
50+
After the traversal, we traverse the array again. If $i+1$ is not equal to $nums[i]$, then $i+1$ is the smallest positive integer we are looking for.
51+
52+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
53+
4654
<!-- tabs:start -->
4755

4856
### **Python3**

solution/0000-0099/0042.Trapping Rain Water/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
**方法一:动态规划**
4545

46-
我们定义 $left[i]$ 表示下标 $i$ 位置及其左边的最高柱子的高度,定义 $right[i]$ 表示下标 $i$ 位置及其右边的最高柱子的高度。那么下标 $i$ 位置能接的雨水量为 $min(left[i], right[i]) - height[i]$。我们遍历数组,计算出 $left[i]$ 和 $right[i]$,最后答案为 $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$。
46+
我们定义 $left[i]$ 表示下标 $i$ 位置及其左边的最高柱子的高度,定义 $right[i]$ 表示下标 $i$ 位置及其右边的最高柱子的高度。那么下标 $i$ 位置能接的雨水量为 $\min(left[i], right[i]) - height[i]$。我们遍历数组,计算出 $left[i]$ 和 $right[i]$,最后答案为 $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$。
4747

4848
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
4949

solution/0000-0099/0042.Trapping Rain Water/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535

3636
**Solution 1: Dynamic Programming**
3737

38-
We define $left[i]$ as the height of the highest pillar to the left of and including the position with index $i$, and define $right[i]$ as the height of the highest pillar to the right of and including the position with index $i$. Then the amount of rain water that can be trapped at the position with index $i$ is $min(left[i], right[i]) - height[i]$. We traverse the array, calculate $left[i]$ and $right[i]$, and the answer is $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$.
38+
We define $left[i]$ as the height of the highest bar to the left of and including the position at index $i$, and $right[i]$ as the height of the highest bar to the right of and including the position at index $i$. Therefore, the amount of rainwater that can be trapped at index $i$ is $min(left[i], right[i]) - height[i]$. We traverse the array to calculate $left[i]$ and $right[i]$, and the final answer is $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$.
3939

40-
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array.
40+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array.
4141

4242
<!-- tabs:start -->
4343

solution/0000-0099/0043.Multiply Strings/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,20 @@
4040

4141
**方法一:数学乘法模拟**
4242

43-
假设 `num1``num2` 的长度分别为 $m$ 和 $n$,则它们的乘积的长度最多为 $m + n$。
43+
假设 $num1$$num2$ 的长度分别为 $m$ 和 $n$,则它们的乘积的长度最多为 $m + n$。
4444

4545
证明如下:
4646

47-
- 如果 `num1``num2` 都取最小值,那么它们的乘积为 ${10}^{m - 1} \times {10}^{n - 1} = {10}^{m + n - 2}$,长度为 $m + n - 1$。
48-
- 如果 `num1``num2` 都取最大值,那么它们的乘积为 $({10}^m - 1) \times ({10}^n - 1) = {10}^{m + n} - {10}^m - {10}^n + 1$,长度为 $m + n$。
47+
- 如果 $num1$$num2$ 都取最小值,那么它们的乘积为 ${10}^{m - 1} \times {10}^{n - 1} = {10}^{m + n - 2}$,长度为 $m + n - 1$。
48+
- 如果 $num1$$num2$ 都取最大值,那么它们的乘积为 $({10}^m - 1) \times ({10}^n - 1) = {10}^{m + n} - {10}^m - {10}^n + 1$,长度为 $m + n$。
4949

5050
因此,我们可以申请一个长度为 $m + n$ 的数组,用于存储乘积的每一位。
5151

5252
从低位到高位,依次计算乘积的每一位,最后将数组转换为字符串即可。
5353

5454
注意判断最高位是否为 $0$,如果是,则去掉。
5555

56-
时间复杂度 $O(m \times n)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为 `num1``num2` 的长度。
56+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为 $num1$$num2$ 的长度。
5757

5858
<!-- tabs:start -->
5959

solution/0000-0099/0043.Multiply Strings/README_EN.md

+17
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@
2727

2828
## Solutions
2929

30+
**Solution 1: Simulating Mathematical Multiplication**
31+
32+
Assume the lengths of $num1$ and $num2$ are $m$ and $n$ respectively, then the length of their product can be at most $m + n$.
33+
34+
The proof is as follows:
35+
36+
- If $num1$ and $num2$ both take the minimum value, then their product is ${10}^{m - 1} \times {10}^{n - 1} = {10}^{m + n - 2}$, with a length of $m + n - 1$.
37+
- If $num1$ and $num2$ both take the maximum value, then their product is $({10}^m - 1) \times ({10}^n - 1) = {10}^{m + n} - {10}^m - {10}^n + 1$, with a length of $m + n$.
38+
39+
Therefore, we can apply for an array of length $m + n$ to store each digit of the product.
40+
41+
From the least significant digit to the most significant digit, we calculate each digit of the product in turn, and finally convert the array into a string.
42+
43+
Note to check whether the most significant digit is $0$, if it is, remove it.
44+
45+
The time complexity is $O(m \times n)$, and the space complexity is $O(m + n)$. Here, $m$ and $n$ are the lengths of $num1$ and $num2$ respectively.
46+
3047
<!-- tabs:start -->
3148

3249
### **Python3**

solution/0000-0099/0044.Wildcard Matching/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
**方法一:动态规划**
6262

63-
定义状态 $dp[i][j]$ 表示 $s$ 的前 $i$ 个字符和 $p$ 的前 $j$ 个字符是否匹配。
63+
我们定义状态 $dp[i][j]$ 表示 $s$ 的前 $i$ 个字符和 $p$ 的前 $j$ 个字符是否匹配。
6464

6565
状态转移方程如下:
6666

@@ -73,7 +73,7 @@ dp[i-1][j-1] \lor dp[i-1][j] \lor dp[i][j-1] & \text{if } p[j-1]=\text{*} \\
7373
\end{cases}
7474
$$
7575

76-
时间复杂度 $O(m\times n)$,空间复杂度 $O(m\times n)$。
76+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为 $s$ 和 $p$ 的长度
7777

7878
<!-- tabs:start -->
7979

solution/0000-0099/0044.Wildcard Matching/README_EN.md

+17
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@
4949

5050
## Solutions
5151

52+
**Solution 1: Dynamic Programming**
53+
54+
We define the state $dp[i][j]$ to represent whether the first $i$ characters of $s$ match the first $j$ characters of $p$.
55+
56+
The state transition equation is as follows:
57+
58+
$$
59+
dp[i][j]=
60+
\begin{cases}
61+
dp[i-1][j-1] & \text{if } s[i-1]=p[j-1] \text{ or } p[j-1]=\text{?} \\
62+
dp[i-1][j-1] \lor dp[i-1][j] \lor dp[i][j-1] & \text{if } p[j-1]=\text{*} \\
63+
\text{false} & \text{otherwise}
64+
\end{cases}
65+
$$
66+
67+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the lengths of $s$ and $p$ respectively.
68+
5269
<!-- tabs:start -->
5370

5471
### **Python3**

solution/0000-0099/0045.Jump Game II/README_EN.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,21 @@
4242

4343
## Solutions
4444

45-
**Solution 1: Greedy**
45+
**Solution 1: Greedy Algorithm**
4646

47-
We can use a variable $mx$ to record the furthest position that can be reached at the current position, and use a variable $last$ to record the last jump position, and use a variable $ans$ to record the number of jumps.
47+
We can use a variable $mx$ to record the farthest position that can be reached from the current position, a variable $last$ to record the position of the last jump, and a variable $ans$ to record the number of jumps.
4848

49-
Next, we traverse the position $i$ of the array $[0,..n - 2]$, and for each position $i$, we can calculate the furthest position that can be reached at the current position through $i + nums[i]$, and we use $mx$ to record this furthest position, that is, $mx = max(mx, i + nums[i])$. Next, we need to determine whether the current position has reached the boundary of the last jump, that is, $i = last$. If so, we need to jump once, update $last$ to $mx$, and increase the number of jumps $ans$ by $1$.
49+
Next, we traverse each position $i$ in $[0,..n - 2]$. For each position $i$, we can calculate the farthest position that can be reached from the current position through $i + nums[i]$. We use $mx$ to record this farthest position, that is, $mx = max(mx, i + nums[i])$. Then, we check whether the current position has reached the boundary of the last jump, that is, $i = last$. If it has reached, then we need to make a jump, update $last$ to $mx$, and increase the number of jumps $ans$ by $1$.
5050

5151
Finally, we return the number of jumps $ans$.
5252

53-
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity $O(1)$.
53+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
54+
55+
Similar problems:
56+
57+
- [55. Jump Game](/solution/0000-0099/0055.Jump%20Game/README_EN.md)
58+
- [1024. Video Stitching](/solution/1000-1099/1024.Video%20Stitching/README_EN.md)
59+
- [1326. Minimum Number of Taps to Open to Water a Garden](/solution/1300-1399/1326.Minimum%20Number%20of%20Taps%20to%20Open%20to%20Water%20a%20Garden/README_EN.md)
5460

5561
<!-- tabs:start -->
5662

solution/0000-0099/0046.Permutations/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
我们设计一个函数 $dfs(i)$ 表示已经填完了前 $i$ 个位置,现在需要填第 $i+1$ 个位置。枚举所有可能的数,如果这个数没有被填过,就填入这个数,然后继续填下一个位置,直到填完所有的位置。
5151

52-
时间复杂度 $O(n\times n!)$,其中 $n$ 是数组的长度。一共有 $n!$ 个排列,每个排列需要 $O(n)$ 的时间来构造。
52+
时间复杂度 $O(n \times n!)$,其中 $n$ 是数组的长度。一共有 $n!$ 个排列,每个排列需要 $O(n)$ 的时间来构造。
5353

5454
相似题目:
5555

solution/0000-0099/0046.Permutations/README_EN.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,15 @@
2828

2929
## Solutions
3030

31-
DFS.
31+
**Solution 1: DFS (Backtracking)**
32+
33+
We design a function $dfs(i)$ to represent that the first $i$ positions have been filled, and now we need to fill the $i+1$ position. We enumerate all possible numbers, if this number has not been filled, we fill in this number, and then continue to fill the next position, until all positions are filled.
34+
35+
The time complexity is $O(n \times n!)$, where $n$ is the length of the array. There are $n!$ permutations in total, and each permutation takes $O(n)$ time to construct.
36+
37+
Similar problems:
38+
39+
- [47. Permutations II](/solution/0000-0099/0047.Permutations%20II/README_EN.md)
3240

3341
<!-- tabs:start -->
3442

solution/0000-0099/0047.Permutations II/README_EN.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,22 @@
3434

3535
## Solutions
3636

37-
Sort & DFS.
37+
**Solution 1: Sorting + Backtracking**
38+
39+
We can first sort the array, which allows us to place duplicate numbers together, making it easier for us to remove duplicates.
40+
41+
Next, we design a function $dfs(i)$, indicating that we need to fill in the number at the $i$th position. The specific implementation of the function is as follows:
42+
43+
- If $i = n$, it means we have finished filling in, add the current permutation to the answer array, and then return.
44+
- Otherwise, we enumerate the number $nums[j]$ at the $i$th position, where the range of $j$ is $[0, n - 1]$. We need to ensure that $nums[j]$ has not been used and is different from the number enumerated before, so as to ensure that the current permutation is not repeated. If the conditions are met, we can fill in $nums[j]$, and continue to recursively fill in the next position, that is, call $dfs(i + 1)$. After the recursive call ends, we need to mark $nums[j]$ as unused for later enumeration.
45+
46+
In the main function, we first sort the array, then call $dfs(0)$, that is, start filling from the 0th position, and finally return the answer array.
47+
48+
The time complexity is $O(n \times n!)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. We need to enumerate $n!$ times, and each enumeration takes $O(n)$ time to judge whether it is repeated. In addition, we need a marker array to mark whether each position has been used, so the space complexity is $O(n)$.
49+
50+
Similar problems:
51+
52+
- [46. Permutations](/solution/0000-0099/0046.Permutations/README_EN.md)
3853

3954
<!-- tabs:start -->
4055

solution/0000-0099/0048.Rotate Image/README_EN.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@
3434

3535
## Solutions
3636

37-
**Solution 1: In-place**
37+
**Solution 1: In-place Rotation**
3838

39-
According to the requirements of the problem, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
39+
According to the problem requirements, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
4040

41-
We can first flip the matrix upside down, that is, swap $matrix[i][j]$ and $matrix[n - i - 1][j]$, and then flip the matrix along the main diagonal, that is, swap $matrix[i][j]$ and $matrix[j][i]$. This way we can rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
41+
We can first flip the matrix upside down, that is, swap $matrix[i][j]$ and $matrix[n - i - 1][j]$, and then flip the matrix along the main diagonal, that is, swap $matrix[i][j]$ and $matrix[j][i]$. This way, we can rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$.
4242

43-
The time complexity is $O(n^2)$, where $n$ is the length of the matrix. And the space complexity is $O(1)$.
43+
The time complexity is $O(n^2)$, where $n$ is the side length of the matrix. The space complexity is $O(1)$.
4444

4545
<!-- tabs:start -->
4646

solution/0000-0099/0049.Group Anagrams/README_EN.md

+24
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,30 @@
3030

3131
## Solutions
3232

33+
**Solution 1: Hash Table**
34+
35+
1. Traverse the string array, sort each string in **character dictionary order** to get a new string.
36+
2. Use the new string as `key` and `[str]` as `value`, and store them in the hash table (`HashMap<String, List<String>>`).
37+
3. When encountering the same `key` during subsequent traversal, add it to the corresponding `value`.
38+
39+
Take `strs = ["eat", "tea", "tan", "ate", "nat", "bat"]` as an example. At the end of the traversal, the state of the hash table is:
40+
41+
| key | value |
42+
| ------- | ----------------------- |
43+
| `"aet"` | `["eat", "tea", "ate"]` |
44+
| `"ant"` | `["tan", "nat"] ` |
45+
| `"abt"` | `["bat"] ` |
46+
47+
Finally, return the `value` list of the hash table.
48+
49+
The time complexity is $O(n\times k\times \log k)$, where $n$ and $k$ are the lengths of the string array and the maximum length of the string, respectively.
50+
51+
**Solution 2: Counting**
52+
53+
We can also change the sorting part in Method 1 to counting, that is, use the characters in each string $s$ and their occurrence times as `key`, and use the string $s$ as `value` to store in the hash table.
54+
55+
The time complexity is $O(n\times (k + C))$, where $n$ and $k$ are the lengths of the string array and the maximum length of the string, respectively, and $C$ is the size of the character set. In this problem, $C = 26$.
56+
3357
<!-- tabs:start -->
3458

3559
### **Python3**

0 commit comments

Comments
 (0)