Skip to content

Commit 45519f2

Browse files
authored
feat: add solutions to lc problems (doocs#2030)
1 parent e13866d commit 45519f2

File tree

44 files changed

+859
-387
lines changed

Some content is hidden

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

44 files changed

+859
-387
lines changed

solution/0000-0099/0002.Add Two Numbers/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
最后我们返回答案链表的头节点即可。
6060

61-
时间复杂度 $O(max(m, n))$,其中 $m$ 和 $n$ 分别为两个链表的长度。我们需要遍历两个链表的全部位置,而处理每个位置只需要 $O(1)$ 的时间。忽略答案的空间消耗,空间复杂度 $O(1)$。
61+
时间复杂度 $O(\max(m, n))$,其中 $m$ 和 $n$ 分别为两个链表的长度。我们需要遍历两个链表的全部位置,而处理每个位置只需要 $O(1)$ 的时间。忽略答案的空间消耗,空间复杂度 $O(1)$。
6262

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

solution/0000-0099/0002.Add Two Numbers/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Each time we traverse, we take out the current bit of the corresponding linked l
5050

5151
Finally, we return the head node of the answer linked list.
5252

53-
The time complexity is $O(max (m, n))$, where $m$ and $n$ are the lengths of the two linked lists. We need to traverse the entire position of the two linked lists, and each position only needs $O(1)$ time. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
53+
The time complexity is $O(\max (m, n))$, where $m$ and $n$ are the lengths of the two linked lists. We need to traverse the entire position of the two linked lists, and each position only needs $O(1)$ time. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
5454

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

solution/0000-0099/0004.Median of Two Sorted Arrays/README_EN.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,24 @@
3939

4040
## Solutions
4141

42-
Binary search.
42+
**Solution 1: Divide and Conquer**
43+
44+
The problem requires the time complexity of the algorithm to be $O(\log (m + n))$, so we cannot directly traverse the two arrays, but need to use the binary search method.
45+
46+
If $m + n$ is odd, then the median is the $\left\lfloor\frac{m + n + 1}{2}\right\rfloor$-th number; if $m + n$ is even, then the median is the average of the $\left\lfloor\frac{m + n + 1}{2}\right\rfloor$-th and the $\left\lfloor\frac{m + n + 2}{2}\right\rfloor$-th numbers. In fact, we can unify it as the average of the $\left\lfloor\frac{m + n + 1}{2}\right\rfloor$-th and the $\left\lfloor\frac{m + n + 2}{2}\right\rfloor$-th numbers.
47+
48+
Therefore, we can design a function $f(i, j, k)$, which represents the $k$-th smallest number in the interval $[i, m)$ of array $nums1$ and the interval $[j, n)$ of array $nums2$. The median is the average of $f(0, 0, \left\lfloor\frac{m + n + 1}{2}\right\rfloor)$ and $f(0, 0, \left\lfloor\frac{m + n + 2}{2}\right\rfloor)$.
49+
50+
The implementation idea of the function $f(i, j, k)$ is as follows:
51+
52+
- If $i \geq m$, it means that the interval $[i, m)$ of array $nums1$ is empty, so directly return $nums2[j + k - 1]$;
53+
- If $j \geq n$, it means that the interval $[j, n)$ of array $nums2$ is empty, so directly return $nums1[i + k - 1]$;
54+
- If $k = 1$, it means to find the first number, so just return the minimum of $nums1[i]$ and $nums2[j]$;
55+
- Otherwise, we find the $\left\lfloor\frac{k}{2}\right\rfloor$-th number in the two arrays, denoted as $x$ and $y$. (Note, if a certain array does not have the $\left\lfloor\frac{k}{2}\right\rfloor$-th number, then we regard the $\left\lfloor\frac{k}{2}\right\rfloor$-th number as $+\infty$.) Compare the size of $x$ and $y$:
56+
- If $x \leq y$, it means that the $\left\lfloor\frac{k}{2}\right\rfloor$-th number of array $nums1$ cannot be the $k$-th smallest number, so we can exclude the interval $[i, i + \left\lfloor\frac{k}{2}\right\rfloor)$ of array $nums1$, and recursively call $f(i + \left\lfloor\frac{k}{2}\right\rfloor, j, k - \left\lfloor\frac{k}{2}\right\rfloor)$.
57+
- If $x > y$, it means that the $\left\lfloor\frac{k}{2}\right\rfloor$-th number of array $nums2$ cannot be the $k$-th smallest number, so we can exclude the interval $[j, j + \left\lfloor\frac{k}{2}\right\rfloor)$ of array $nums2$, and recursively call $f(i, j + \left\lfloor\frac{k}{2}\right\rfloor, k - \left\lfloor\frac{k}{2}\right\rfloor)$.
58+
59+
The time complexity is $O(\log(m + n))$, and the space complexity is $O(\log(m + n))$. Here, $m$ and $n$ are the lengths of arrays $nums1$ and $nums2$ respectively.
4360

4461
<!-- tabs:start -->
4562

solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md

+10-7
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,21 @@
3434

3535
**Solution 1: Dynamic Programming**
3636

37-
Set $dp[i][j]$ to indicate whether the string $s[i..j]$ is a palindrome.
37+
We define $f[i][j]$ to represent whether the string $s[i..j]$ is a palindrome, initially $f[i][j] = true$.
3838

39-
- When $j - i \lt 2$, that is, the string length is `2`, as long as $s[i] == s[j]$, then $dp[i][j]$ is `true`.
40-
- When $j - i \ge 2$, there is $dp[i][j] = dp[i + 1][j - 1] \cap s[i] == s[j]$.
39+
Next, we define variables $k$ and $mx$, where $k$ represents the starting position of the longest palindrome, and $mx$ represents the length of the longest palindrome. Initially, $k = 0$, $mx = 1$.
4140

42-
The time complexity is $O(n^2)$ and the space complexity is $O(n^2)$. Where $n$ is the length of the string $s$.
41+
Considering $f[i][j]$, if $s[i] = s[j]$, then $f[i][j] = f[i + 1][j - 1]$; otherwise, $f[i][j] = false$. If $f[i][j] = true$ and $mx < j - i + 1$, then we update $k = i$, $mx = j - i + 1$.
4342

44-
**Solution 2: Enumerate the Palindrome Center**
43+
Since $f[i][j]$ depends on $f[i + 1][j - 1]$, we need to ensure that $i + 1$ is before $j - 1$, so we need to enumerate $i$ from large to small, and enumerate $j$ from small to large.
4544

46-
We can enumerate the palindrome center, spread to both sides, and find the longest palindrome.
45+
The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string $s$.
4746

48-
The time complexity is $O(n^2)$ and the space complexity is $O(1)$. Where $n$ is the length of the string $s$.
47+
**Solution 2: Enumerate Palindrome Midpoint**
48+
49+
We can enumerate the midpoint of the palindrome, spread to both sides, and find the longest palindrome.
50+
51+
The time complexity is $O(n^2)$, and the space complexity is $O(1)$. Here, $n$ is the length of the string $s$.
4952

5053
<!-- tabs:start -->
5154

solution/0000-0099/0006.Zigzag Conversion/README_EN.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ P I
6060

6161
**Solution 1: Simulation**
6262

63-
We use a 2D array $g$ to simulate the process of the $Z$-shaped arrangement, where $g[i][j]$ represents the character in the $i$th row and the $j$th column. Initially, $i=0$, and we also define a direction variable $k$, initially $k=-1$, which means up.
63+
We use a two-dimensional array $g$ to simulate the process of the $Z$-shape arrangement, where $g[i][j]$ represents the character at the $i$-th row and the $j$-th column. Initially, $i=0$, and we define a direction variable $k$, initially $k=-1$, indicating moving upwards.
6464

65-
We traverse the string $s$ from left to right. Each time we traverse a character $c$, we append it to $g[i]$. If at this time $i=0$ or $i=numRows-1$, it means that the current character is at the turning point of the $Z$-shaped arrangement. We reverse the value of $k$, that is, $k=-k$. Next, we update the value of $i$ to $i+k$, that is, move up or down one row. Continue to traverse the next character until the string $s$ is traversed. We return the string that all rows in $g$ are concatenated.
65+
We traverse the string $s$ from left to right. Each time we traverse to a character $c$, we append it to $g[i]$. If $i=0$ or $i=numRows-1$ at this time, it means that the current character is at the turning point of the $Z$-shape arrangement, and we reverse the value of $k$, i.e., $k=-k$. Next, we update the value of $i$ to $i+k$, i.e., move up or down one row. Continue to traverse the next character until we have traversed the string $s$, and we return the string concatenated by all rows in $g$.
6666

67-
Time complexity $O(n)$, space complexity $O(n)$, where $n$ is the length of the string $s$.
67+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $s$.
6868

6969
<!-- tabs:start -->
7070

solution/0000-0099/0007.Reverse Integer/README_EN.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,27 @@
3939

4040
## Solutions
4141

42-
**Solution 1: Mathematical**
42+
**Solution 1: Mathematics**
4343

44-
Let $mi$ and $mx$ be $-2^{31}$ and $2^{31} - 1$ respectively. The reversed result $ans$ needs to satisfy $mi \le ans \le mx$.
44+
Let's denote $mi$ and $mx$ as $-2^{31}$ and $2^{31} - 1$ respectively, then the reverse result of $x$, $ans$, needs to satisfy $mi \le ans \le mx$.
4545

46-
We can get the last digit $y$ of $x$ by repeatedly taking the remainder of $x$ by $10$, and then add $y$ to the end of $ans$. Before adding $y$, we need to determine whether $ans$ will overflow. That is, whether $ans \times 10 + y$ is within the range $[mi, mx]$.
46+
We can continuously take the remainder of $x$ to get the last digit $y$ of $x$, and add $y$ to the end of $ans$. Before adding $y$, we need to check if $ans$ overflows. That is, check whether $ans \times 10 + y$ is within the range $[mi, mx]$.
4747

48-
If $x \gt 0$, then $ans \times 10 + y \leq mx$ should be satisfied. That is, $ans \times 10 + y \leq \left \lfloor \frac{mx}{10} \right \rfloor \times 10 + 7$. Rearrange to get $(ans - \left \lfloor \frac{mx}{10} \right \rfloor) \times 10 \leq 7 - y$.
48+
If $x \gt 0$, it needs to satisfy $ans \times 10 + y \leq mx$, that is, $ans \times 10 + y \leq \left \lfloor \frac{mx}{10} \right \rfloor \times 10 + 7$. Rearranging gives $(ans - \left \lfloor \frac{mx}{10} \right \rfloor) \times 10 \leq 7 - y$.
4949

50-
The following conditions need to be satisfied for the above inequality to hold:
50+
Next, we discuss the conditions for the inequality to hold:
5151

5252
- When $ans \lt \left \lfloor \frac{mx}{10} \right \rfloor$, the inequality obviously holds;
53-
- When $ans = \left \lfloor \frac{mx}{10} \right \rfloor$, the necessary and sufficient conditions for the above inequality to hold are $y \leq 7$. If $ans = \left \lfloor \frac{mx}{10} \right \rfloor$ and can still continue to add digits, it means that the current digit is the most significant digit. Therefore, $y$ must be less than or equal to $2$, so the inequality must hold;
53+
- When $ans = \left \lfloor \frac{mx}{10} \right \rfloor$, the necessary and sufficient condition for the inequality to hold is $y \leq 7$. If $ans = \left \lfloor \frac{mx}{10} \right \rfloor$ and we can still add numbers, it means that the number is at the highest digit, that is, $y$ must not exceed $2$, therefore, the inequality must hold;
5454
- When $ans \gt \left \lfloor \frac{mx}{10} \right \rfloor$, the inequality obviously does not hold.
5555

56-
Therefore, when $x \gt 0$, the necessary and sufficient conditions for the inequality to hold are $ans \leq \left \lfloor \frac{mx}{10} \right \rfloor$.
56+
In summary, when $x \gt 0$, the necessary and sufficient condition for the inequality to hold is $ans \leq \left \lfloor \frac{mx}{10} \right \rfloor$.
5757

58-
Similarly, when $x \lt 0$, the necessary and sufficient conditions for the inequality to hold are $ans \geq \left \lfloor \frac{mi}{10} \right \rfloor$.
58+
Similarly, when $x \lt 0$, the necessary and sufficient condition for the inequality to hold is $ans \geq \left \lfloor \frac{mi}{10} \right \rfloor$.
5959

60-
Therefore, we can determine whether $ans$ will overflow by determining whether $ans$ is within the range $[\left \lfloor \frac{mi}{10} \right \rfloor, \left \lfloor \frac{mx}{10} \right \rfloor]$. If so, return $0$. Otherwise, add $y$ to the end of $ans$, and then remove the last digit of $x$, that is, $x \gets \left \lfloor \frac{x}{10} \right \rfloor$.
60+
Therefore, we can check whether $ans$ overflows by checking whether $ans$ is within the range $[\left \lfloor \frac{mi}{10} \right \rfloor, \left \lfloor \frac{mx}{10} \right \rfloor]$. If it overflows, return $0$. Otherwise, add $y$ to the end of $ans$, and then remove the last digit of $x$, that is, $x \gets \left \lfloor \frac{x}{10} \right \rfloor$.
6161

62-
Time complexity $O(\log |x|)$, where $|x|$ is the absolute value of $x$. Space complexity $O(1)$.
62+
The time complexity is $O(\log |x|)$, where $|x|$ is the absolute value of $x$. The space complexity is $O(1)$.
6363

6464
<!-- tabs:start -->
6565

solution/0000-0099/0008.String to Integer (atoi)/README.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,17 @@
8888

8989
<!-- 这里可写通用的实现逻辑 -->
9090

91-
遍历字符串,注意做溢出处理。
91+
**方法一:遍历字符串**
92+
93+
我们首先判断字符串是否为空,如果是,直接返回 $0$。
94+
95+
否则,我们需要遍历字符串,跳过前导空格,判断第一个非空格字符是否为正负号。
96+
97+
接着遍历后面的字符,如果是数字,我们判断添加该数字是否会导致整数溢出,如果会,我们根据正负号返回结果。否则我们将数字添加到结果中。继续遍历后面的字符,直到遇到非数字字符或者遍历结束。
98+
99+
遍历结束后,我们根据正负号返回结果。
100+
101+
时间复杂度 $O(n)$,其中 $n$ 为字符串的长度。我们只需要依次处理所有字符。空间复杂度 $O(1)$。
92102

93103
[面试题 67. 把字符串转换成整数](/lcof/面试题67.%20把字符串转换成整数/README.md)
94104

solution/0000-0099/0008.String to Integer (atoi)/README_EN.md

+12
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ Since 4193 is in the range [-2<sup>31</sup>, 2<sup>31</sup> - 1], the final resu
8383

8484
## Solutions
8585

86+
**Solution 1: Traverse the String**
87+
88+
First, we determine whether the string is empty. If it is, we directly return $0$.
89+
90+
Otherwise, we need to traverse the string, skip the leading spaces, and determine whether the first non-space character is a positive or negative sign.
91+
92+
Then we traverse the following characters. If it is a digit, we judge whether adding this digit will cause integer overflow. If it does, we return the result according to the positive or negative sign. Otherwise, we add the digit to the result. We continue to traverse the following characters until we encounter a non-digit character or the traversal ends.
93+
94+
After the traversal ends, we return the result according to the positive or negative sign.
95+
96+
The time complexity is $O(n)$, where $n$ is the length of the string. We only need to process all characters in turn. The space complexity is $O(1)$.
97+
8698
<!-- tabs:start -->
8799

88100
### **Python3**

solution/0000-0099/0009.Palindrome Number/README_EN.md

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

4444
## Solutions
4545

46+
**Solution 1: Reverse Half of the Number**
47+
48+
First, we determine special cases:
49+
50+
- If $x < 0$, then $x$ is not a palindrome, directly return `false`;
51+
- If $x > 0$ and the last digit of $x$ is $0$, then $x$ is not a palindrome, directly return `false`;
52+
- If the last digit of $x$ is not $0$, then $x$ might be a palindrome, continue the following steps.
53+
54+
We reverse the second half of $x$ and compare it with the first half. If they are equal, then $x$ is a palindrome, otherwise, $x$ is not a palindrome.
55+
56+
For example, for $x = 1221$, we can reverse the second half from "21" to "12" and compare it with the first half "12". Since they are equal, we know that $x$ is a palindrome.
57+
58+
Let's see how to reverse the second half.
59+
60+
For the number $1221$, if we perform $1221 \bmod 10$, we will get the last digit $1$. To get the second last digit, we can first remove the last digit from $1221$ by dividing by $10$, $1221 / 10 = 122$, then get the remainder of the previous result divided by $10$, $122 \bmod 10 = 2$, to get the second last digit.
61+
62+
If we continue this process, we will get more reversed digits.
63+
64+
By continuously multiplying the last digit to the variable $y$, we can get the number in reverse order.
65+
66+
In the code implementation, we can repeatedly "take out" the last digit of $x$ and "add" it to the end of $y$, loop until $y \ge x$. If at this time $x = y$, or $x = y / 10$, then $x$ is a palindrome.
67+
68+
The time complexity is $O(\log_{10}(n))$, where $n$ is $x$. For each iteration, we will divide the input by $10$, so the time complexity is $O(\log_{10}(n))$. The space complexity is $O(1)$.
69+
4670
<!-- tabs:start -->
4771

4872
### **Python3**

solution/0000-0099/0010.Regular Expression Matching/README_EN.md

+27
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,33 @@
5151

5252
## Solutions
5353

54+
**Solution 1: Memoization Search**
55+
56+
We design a function $dfs(i, j)$, which indicates whether the $i$-th character of $s$ matches the $j$-th character of $p$. The answer is $dfs(0, 0)$.
57+
58+
The calculation process of the function $dfs(i, j)$ is as follows:
59+
60+
- If $j$ has reached the end of $p$, then if $i$ has also reached the end of $s$, the match is successful, otherwise, the match fails.
61+
- If the next character of $j$ is `'*'`, we can choose to match $0$ $s[i]$ characters, which is $dfs(i, j + 2)$. If $i \lt m$ and $s[i]$ matches $p[j]$, we can choose to match $1$ $s[i]$ character, which is $dfs(i + 1, j)$.
62+
- If the next character of $j$ is not `'*'`, then if $i \lt m$ and $s[i]$ matches $p[j]$, it is $dfs(i + 1, j + 1)$. Otherwise, the match fails.
63+
64+
During the process, we can use memoization search to avoid repeated calculations.
65+
66+
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.
67+
68+
**Solution 2: Dynamic Programming**
69+
70+
We can convert the memoization search in Solution 1 into dynamic programming.
71+
72+
Define $f[i][j]$ to represent whether the first $i$ characters of string $s$ match the first $j$ characters of string $p$. The answer is $f[m][n]$. Initialize $f[0][0] = true$, indicating that the empty string and the empty regular expression match.
73+
74+
Similar to Solution 1, we can discuss different cases.
75+
76+
- If $p[j - 1]$ is `'*'`, we can choose to match $0$ $s[i - 1]$ characters, which is $f[i][j] = f[i][j - 2]$. If $s[i - 1]$ matches $p[j - 2]$, we can choose to match $1$ $s[i - 1]$ character, which is $f[i][j] = f[i][j] \lor f[i - 1][j]$.
77+
- If $p[j - 1]$ is not `'*'`, then if $s[i - 1]$ matches $p[j - 1]$, it is $f[i][j] = f[i - 1][j - 1]$. Otherwise, the match fails.
78+
79+
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.
80+
5481
<!-- tabs:start -->
5582

5683
### **Python3**

solution/0000-0099/0011.Container With Most Water/README_EN.md

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939

4040
## Solutions
4141

42+
**Solution 1: Two Pointers**
43+
44+
Initially, we consider the capacity of the water that the two farthest pillars can hold. The width of the water is the distance between the two pillars, and the height of the water depends on the shorter one between the two pillars.
45+
46+
The current pillars are the pillars on the farthest sides, so the width of the water is the largest. For other combinations, the width of the water is smaller. Suppose the height of the left pillar is less than or equal to the height of the right pillar, then the height of the water is the height of the left pillar. If we move the right pillar, the width of the water will decrease, but the height of the water will not increase, so the capacity of the water will definitely decrease. Therefore, we move the left pillar and update the maximum capacity.
47+
48+
Repeat this process until the two pillars meet.
49+
50+
The time complexity is $O(n)$, where $n$ is the length of the array `height`. The space complexity is $O(1)$.
51+
4252
<!-- tabs:start -->
4353

4454
### **Python3**

solution/0000-0099/0012.Integer to Roman/README_EN.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ M 1000</pre>
6464

6565
**Solution 1: Greedy**
6666

67-
We can list all possible symbols $cs$ and corresponding values $vs$ first, then enumerate the value $vs[i]$ from large to small, and use the symbol $cs[i]$ as much as possible each time until the number $num$ becomes $0$.
67+
We can first list all possible symbols $cs$ and their corresponding values $vs$, then enumerate each value $vs[i]$ from large to small. Each time, we use as many symbols $cs[i]$ corresponding to this value as possible, until the number $num$ becomes $0$.
6868

69-
The time complexity is $O(m)$ and the space complexity is $O(m)$, where $m$ is the number of symbols.
69+
The time complexity is $O(m)$, and the space complexity is $O(m)$. Here, $m$ is the number of symbols.
7070

7171
<!-- tabs:start -->
7272

0 commit comments

Comments
 (0)