Skip to content

Commit 7321fbc

Browse files
authored
feat: add solutions to lc problems (doocs#2036)
1 parent fff021e commit 7321fbc

File tree

25 files changed

+410
-137
lines changed

25 files changed

+410
-137
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ The time complexity is $O(n\times k\times \log k)$, where $n$ and $k$ are the le
5050

5151
**Solution 2: Counting**
5252

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.
53+
We can also change the sorting part in Solution 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.
5454

5555
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$.
5656

solution/0100-0199/0122.Best Time to Buy and Sell Stock II/README_EN.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,21 @@ Total profit is 4.
4848

4949
## Solutions
5050

51-
**Solution 1: Greedy**
51+
**Solution 1: Greedy Algorithm**
5252

53-
From the second day, if the stock price on that day is greater than the previous day, buy it on the previous day and sell it on that day to get a profit. If the stock price on that day is less than the previous day, do not buy it or sell it. That is to say, all the rising trading days are bought and sold, and all the falling trading days are not bought or sold, and the final profit is the maximum.
53+
Starting from the second day, if the stock price is higher than the previous day, buy on the previous day and sell on the current day to make a profit. If the stock price is lower than the previous day, do not buy or sell. In other words, buy and sell on all rising trading days, and do not trade on all falling trading days. The final profit will be the maximum.
5454

55-
The time complexity is $O(n)$, where $n$ is the length of the array `prices`. The space complexity is $O(1)$.
55+
The time complexity is $O(n)$, where $n$ is the length of the `prices` array. The space complexity is $O(1)$.
5656

5757
**Solution 2: Dynamic Programming**
5858

59-
Let $f[i][j]$ represent the maximum profit after the $i$th day of trading, where $j$ represents whether the current stock is held, and $j=0$ when the stock is held, and $j=1$ when the stock is not held. The initial state is $f[0][0]=-prices[0]$, and all other states are $0$.
59+
We define $f[i][j]$ as the maximum profit after trading on the $i$th day, where $j$ indicates whether we currently hold the stock. When holding the stock, $j=0$, and when not holding the stock, $j=1$. The initial state is $f[0][0]=-prices[0]$, and all other states are $0$.
6060

61-
If the current stock is held, it may be that the stock was held on the previous day and nothing was done today, that is, $f[i][0]=f[i-1][0]$; or the stock was not held the previous day and the stock was bought today, that is, $f[i][0]=f[i-1][1]-prices[i]$.
61+
If we currently hold the stock, it may be that we held the stock the day before and do nothing today, i.e., $f[i][0]=f[i-1][0]$. Or it may be that we did not hold the stock the day before and bought the stock today, i.e., $f[i][0]=f[i-1][1]-prices[i]$.
6262

63-
If the current stock is not held, it may be that the stock was not held the previous day and nothing was done today, that is, $f[i][1]=f[i-1][1]$; or the stock was held the previous day and the stock was sold today, that is, $f[i][1]=f[i-1][0]+prices[i]$.
63+
If we currently do not hold the stock, it may be that we did not hold the stock the day before and do nothing today, i.e., $f[i][1]=f[i-1][1]$. Or it may be that we held the stock the day before and sold the stock today, i.e., $f[i][1]=f[i-1][0]+prices[i]$.
6464

65-
Therefore, we can write down the state transition equation:
65+
Therefore, we can write the state transition equation as:
6666

6767
$$
6868
\begin{cases}
@@ -71,15 +71,15 @@ f[i][1]=\max(f[i-1][1],f[i-1][0]+prices[i])
7171
\end{cases}
7272
$$
7373

74-
The final answer is $f[n-1][1]$, where $n$ is the length of the array `prices`.
74+
The final answer is $f[n-1][1]$, where $n$ is the length of the `prices` array.
7575

76-
The time complexity is $O(n)$ and the space complexity is $O(n)$. $n$ is the length of the array `prices`.
76+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the `prices` array.
7777

78-
**Solution 3: Dynamic Programming (space optimization)**
78+
**Solution 3: Dynamic Programming (Space Optimization)**
7979

80-
We can find that in Solution 2, the state of the $i$th day only depends on the state of the $i-1$th day, so we can only use two variables to maintain the state of the $i-1$th day. Therefore, the space complexity can be optimized to $O(1)$.
80+
We can find that in Solution 2, the state of the $i$th day is only related to the state of the $i-1$th day. Therefore, we can use only two variables to maintain the state of the $i-1$th day, thereby optimizing the space complexity to $O(1)$.
8181

82-
Time complexity $O(n)$, where $n$ is the length of the array `prices`. Space complexity $O(1)$.
82+
The time complexity is $O(n)$, where $n$ is the length of the `prices` array. The space complexity is $O(1)$.
8383

8484
<!-- tabs:start -->
8585

solution/0100-0199/0123.Best Time to Buy and Sell Stock III/README_EN.md

+15
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
4646

4747
## Solutions
4848

49+
**Solution 1: Dynamic Programming**
50+
51+
We define the following variables:
52+
53+
- `f1` represents the maximum profit after the first purchase of the stock;
54+
- `f2` represents the maximum profit after the first sale of the stock;
55+
- `f3` represents the maximum profit after the second purchase of the stock;
56+
- `f4` represents the maximum profit after the second sale of the stock.
57+
58+
During the traversal, we directly calculate `f1`, `f2`, `f3`, `f4`. We consider that buying and selling on the same day will result in a profit of $0$, which will not affect the answer.
59+
60+
Finally, return `f4`.
61+
62+
The time complexity is $O(n)$, where $n$ is the length of the `prices` array. The space complexity is $O(1)$.
63+
4964
<!-- tabs:start -->
5065

5166
### **Python3**

solution/0100-0199/0124.Binary Tree Maximum Path Sum/README_EN.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,25 @@
3939

4040
**Solution 1: Recursion**
4141

42-
We think about the classic routine of binary tree recursion problem:
42+
When thinking about the classic routine of recursion problems in binary trees, we consider:
4343

4444
1. Termination condition (when to terminate recursion)
45-
2. Recursion processing left and right subtrees
46-
3. Combine the calculation results of the left and right subtrees
45+
2. Recursively process the left and right subtrees
46+
3. Merge the calculation results of the left and right subtrees
4747

48-
For this topic, we design a function $dfs(root)$, which returns the maximum path sum of the binary tree with $root$ as the root node.
48+
For this problem, we design a function $dfs(root)$, which returns the maximum path sum of the binary tree with $root$ as the root node.
4949

5050
The execution logic of the function $dfs(root)$ is as follows:
5151

5252
If $root$ does not exist, then $dfs(root)$ returns $0$;
5353

54-
Otherwise, we recursively calculate the maximum path sum of the left subtree and the right subtree of $root$, denoted as $left$ and $right$, respectively. If $left$ is less than $0$, then we set it to $0$, similarly, if $right$ is less than $0$, then we set it to $0$.
54+
Otherwise, we recursively calculate the maximum path sum of the left and right subtrees of $root$, denoted as $left$ and $right$. If $left$ is less than $0$, then we set it to $0$, similarly, if $right$ is less than $0$, then we set it to $0$.
5555

5656
Then, we update the answer with $root.val + left + right$. Finally, the function returns $root.val + \max(left, right)$.
5757

58-
In the main function, we call $dfs(root)$ to get the maximum path sum of each node, and the maximum value in it is the answer.
58+
In the main function, we call $dfs(root)$ to get the maximum path sum of each node, and the maximum value among them is the answer.
5959

60-
Time complexity $O(n)$, space complexity $O(n)$. Where $n$ is the number of nodes in the binary tree.
60+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
6161

6262
<!-- tabs:start -->
6363

solution/0100-0199/0125.Valid Palindrome/README_EN.md

+13
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ Since an empty string reads the same forward and backward, it is a palindrome.
4444

4545
## Solutions
4646

47+
**Solution 1: Two Pointers**
48+
49+
We use two pointers $i$ and $j$ to point to the two ends of the string $s$, and then loop through the following process until $i \geq j$:
50+
51+
1. If $s[i]$ is not a letter or a number, move the pointer $i$ one step to the right and continue to the next loop.
52+
2. If $s[j]$ is not a letter or a number, move the pointer $j$ one step to the left and continue to the next loop.
53+
3. If the lowercase form of $s[i]$ and $s[j]$ are not equal, return `false`.
54+
4. Otherwise, move the pointer $i$ one step to the right and the pointer $j$ one step to the left, and continue to the next loop.
55+
56+
At the end of the loop, return `true`.
57+
58+
The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(1)$.
59+
4760
<!-- tabs:start -->
4861

4962
### **Python3**

solution/0100-0199/0127.Word Ladder/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53+
**方法一:BFS**
54+
5355
BFS 最小步数模型。本题可以用朴素 BFS,也可以用双向 BFS 优化搜索空间,从而提升效率。
5456

5557
双向 BFS 是 BFS 常见的一个优化方法,主要实现思路如下:

solution/0100-0199/0127.Word Ladder/README_EN.md

+35-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,41 @@
4646

4747
## Solutions
4848

49-
BFS.
49+
**Solution 1: BFS**
50+
51+
BFS minimum step model. This problem can be solved with naive BFS, or it can be optimized with bidirectional BFS to reduce the search space and improve efficiency.
52+
53+
Bidirectional BFS is a common optimization method for BFS, with the main implementation ideas as follows:
54+
55+
1. Create two queues, q1 and q2, for "start -> end" and "end -> start" search directions, respectively.
56+
2. Create two hash maps, m1 and m2, to record the visited nodes and their corresponding expansion times (steps).
57+
3. During each search, prioritize the queue with fewer elements for search expansion. If a node visited from the other direction is found during the expansion, it means the shortest path has been found.
58+
4. If one of the queues is empty, it means that the search in the current direction cannot continue, indicating that the start and end points are not connected, and there is no need to continue the search.
59+
60+
```python
61+
while q1 and q2:
62+
if len(q1) <= len(q2):
63+
# Prioritize the queue with fewer elements for expansion
64+
extend(m1, m2, q1)
65+
else:
66+
extend(m2, m1, q2)
67+
68+
69+
def extend(m1, m2, q):
70+
# New round of expansion
71+
for _ in range(len(q)):
72+
p = q.popleft()
73+
step = m1[p]
74+
for t in next(p):
75+
if t in m1:
76+
# Already visited before
77+
continue
78+
if t in m2:
79+
# The other direction has been searched, indicating that a shortest path has been found
80+
return step + 1 + m2[t]
81+
q.append(t)
82+
m1[t] = step + 1
83+
```
5084

5185
<!-- tabs:start -->
5286

solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,23 @@
3636

3737
**Solution 1: Sorting**
3838

39-
First, we sort the array, and use a variable $t$ to record the length of the current continuous sequence, and use a variable $ans$ to record the length of the longest continuous sequence.
39+
First, we sort the array, then use a variable $t$ to record the current length of the consecutive sequence, and a variable $ans$ to record the length of the longest consecutive sequence.
4040

41-
Then, we start to traverse the array from index $i=1$, for the current element $nums[i]$:
41+
Next, we start traversing the array from index $i=1$. For the current element $nums[i]$:
4242

43-
- If $nums[i]=nums[i-1]$ , then the current element is duplicate, and we don't need to consider it;
44-
- If $nums[i]=nums[i-1]+1$ , then the current element can be connected to the previous continuous sequence to form a longer continuous sequence, so we update $t = t + 1$ and update the answer $ans = \max(ans, t)$;
45-
- Otherwise, the current element cannot be connected to the previous continuous sequence, so we reset $t$ to $1$.
43+
- If $nums[i] = nums[i-1]$, it means the current element is repeated and does not need to be considered.
44+
- If $nums[i] = nums[i-1] + 1$, it means the current element can be appended to the previous consecutive sequence to form a longer consecutive sequence. We update $t = t + 1$, and then update the answer $ans = \max(ans, t)$.
45+
- Otherwise, it means the current element cannot be appended to the previous consecutive sequence, and we reset $t$ to $1$.
4646

4747
Finally, we return the answer $ans$.
4848

49-
Time complexity $O(n \times \log n)$, space complexity $O(\log n)$, where $n$ is the length of the array.
49+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$. Here, $n$ is the length of the array.
5050

5151
**Solution 2: Hash Table**
5252

53-
We use a hash table to store all the elements in the array, and then we traverse the array to find the longest continuous sequence for each element $x$. If the predecessor of the current element $x-1$ is not in the hash table, we use the current element as the starting point, and keep trying to match $x+1, x+2, x+3, \dots$ until we cannot match, the matching length at this time is the length of the longest continuous sequence starting from $x$, so we update the answer.
53+
We use a hash table to store all elements in the array, and then traverse each element $x$ in the array. If the predecessor $x-1$ of the current element is not in the hash table, then we start with the current element and continuously try to match $x+1, x+2, x+3, \dots$, until no match is found. The length of the match at this time is the longest consecutive sequence length starting with $x$, and we update the answer accordingly.
5454

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

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

solution/0100-0199/0129.Sum Root to Leaf Numbers/README_EN.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,18 @@ Therefore, sum = 495 + 491 + 40 = <code>1026</code>.
5151

5252
## Solutions
5353

54-
DFS.
54+
**Solution 1: DFS**
55+
56+
We can design a function $dfs(root, s)$, which represents the sum of all path numbers from the current node $root$ to the leaf nodes, given that the current path number is $s$. The answer is $dfs(root, 0)$.
57+
58+
The calculation of the function $dfs(root, s)$ is as follows:
59+
60+
- If the current node $root$ is null, return $0$.
61+
- Otherwise, add the value of the current node to $s$, i.e., $s = s \times 10 + root.val$.
62+
- If the current node is a leaf node, return $s$.
63+
- Otherwise, return $dfs(root.left, s) + dfs(root.right, s)$.
64+
65+
The time complexity is $O(n)$, and the space complexity is $O(\log n)$. Here, $n$ is the number of nodes in the binary tree.
5566

5667
<!-- tabs:start -->
5768

solution/0100-0199/0191.Number of 1 Bits/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,13 @@ int hammingWeight(uint32_t n) {
262262
```
263263
264264
### **Typescript**
265+
265266
```ts
266267
function hammingWeight(n: number): number {
267268
let ans: number = 0;
268269
while (n !== 0) {
269270
ans++;
270-
n &= (n - 1);
271+
n &= n - 1;
271272
}
272273
return ans;
273274
}

solution/0100-0199/0191.Number of 1 Bits/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,18 @@ int hammingWeight(uint32_t n) {
212212
```
213213
214214
### **Typescript**
215+
215216
```ts
216217
function hammingWeight(n: number): number {
217218
let ans: number = 0;
218219
while (n !== 0) {
219220
ans++;
220-
n &= (n - 1);
221+
n &= n - 1;
221222
}
222223
return ans;
223224
}
224225
```
225226

226-
227227
### **...**
228228

229229
```
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
function hammingWeight(n: number): number {
2-
let ans: number = 0;
3-
while (n !== 0) {
4-
ans++;
5-
n &= (n - 1);
6-
}
7-
return ans;
8-
}
1+
function hammingWeight(n: number): number {
2+
let ans: number = 0;
3+
while (n !== 0) {
4+
ans++;
5+
n &= n - 1;
6+
}
7+
return ans;
8+
}

solution/2600-2699/2660.Determine the Winner of a Bowling Game/README.md

+16-24
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,7 @@ class Solution:
9595
return s
9696

9797
a, b = f(player1), f(player2)
98-
if a > b:
99-
return 1
100-
if b > a:
101-
return 2
102-
return 0
98+
return 1 if a > b else (2 if b > a else 0)
10399
```
104100

105101
### **Java**
@@ -130,18 +126,16 @@ class Solution {
130126
class Solution {
131127
public:
132128
int isWinner(vector<int>& player1, vector<int>& player2) {
129+
auto f = [](vector<int>& arr) {
130+
int s = 0;
131+
for (int i = 0, n = arr.size(); i < n; ++i) {
132+
int k = (i && arr[i - 1] == 10) || (i > 1 && arr[i - 2] == 10) ? 2 : 1;
133+
s += k * arr[i];
134+
}
135+
return s;
136+
};
133137
int a = f(player1), b = f(player2);
134-
return a > b ? 1 : b > a ? 2
135-
: 0;
136-
}
137-
138-
int f(vector<int>& arr) {
139-
int s = 0;
140-
for (int i = 0; i < arr.size(); ++i) {
141-
int k = (i > 0 && arr[i - 1] == 10) || (i > 1 && arr[i - 2] == 10) ? 2 : 1;
142-
s += k * arr[i];
143-
}
144-
return s;
138+
return a > b ? 1 : (b > a ? 2 : 0);
145139
}
146140
};
147141
```
@@ -199,24 +193,22 @@ impl Solution {
199193
pub fn is_winner(player1: Vec<i32>, player2: Vec<i32>) -> i32 {
200194
let f = |arr: &Vec<i32>| -> i32 {
201195
let mut s = 0;
202-
203196
for i in 0..arr.len() {
204197
let mut k = 1;
205198
if (i > 0 && arr[i - 1] == 10) || (i > 1 && arr[i - 2] == 10) {
206199
k = 2;
207200
}
208201
s += k * arr[i];
209202
}
210-
211203
s
212204
};
213205

214-
let p1 = f(&player1);
215-
let p2 = f(&player2);
216-
if p1 > p2 {
217-
return 1;
218-
} else if p1 < p2 {
219-
return 2;
206+
let a = f(&player1);
207+
let b = f(&player2);
208+
if a > b {
209+
1
210+
} else if a < b {
211+
2
220212
} else {
221213
0
222214
}

0 commit comments

Comments
 (0)