Skip to content

Commit f901522

Browse files
authored
feat: update solutions to lcci problems (doocs#2088)
1 parent 06fff4b commit f901522

File tree

18 files changed

+264
-7
lines changed

18 files changed

+264
-7
lines changed

lcci/04.12.Paths with Sum/README_EN.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ Given the following tree and &nbsp;<code>sum = 22,</code></p>
4444

4545
## Solutions
4646

47+
**Solution 1: Hash Table + Prefix Sum + Recursion**
48+
49+
We can use the idea of prefix sum to recursively traverse the binary tree, and use a hash table $cnt$ to count the occurrence of each prefix sum on the path from the root node to the current node.
50+
51+
We design a recursive function $dfs(node, s)$, where the current node being traversed is $node$, and the prefix sum on the path from the root node to the current node is $s$. The return value of the function is the number of paths with the path sum equal to $sum$ and the path ends at the $node$ node or its subtree nodes. Therefore, the answer is $dfs(root, 0)$.
52+
53+
The recursive process of the function $dfs(node, s)$ is as follows:
54+
55+
- If the current node $node$ is null, return $0$.
56+
- Calculate the prefix sum $s$ on the path from the root node to the current node.
57+
- Use $cnt[s - sum]$ to represent the number of paths with the path sum equal to $sum$ and the path ends at the current node, where $cnt[s - sum]$ is the count of the prefix sum equal to $s - sum$ in $cnt$.
58+
- Add the count of the prefix sum $s$ by $1$, i.e., $cnt[s] = cnt[s] + 1$.
59+
- Recursively traverse the left and right child nodes of the current node, i.e., call the functions $dfs(node.left, s)$ and $dfs(node.right, s)$, and add their return values.
60+
- After the return value is calculated, subtract the count of the prefix sum $s$ of the current node by $1$, i.e., execute $cnt[s] = cnt[s] - 1$.
61+
- Finally, return the answer.
62+
63+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree.
64+
4765
<!-- tabs:start -->
4866

4967
### **Python3**

lcci/05.01.Insert Into Bits/README_EN.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
## Solutions
2626

27+
**Solution 1: Bit Manipulation**
28+
29+
First, we clear the bits from the $i$-th to the $j$-th in $N$, then we left shift $M$ by $i$ bits, and finally perform a bitwise OR operation on $M$ and $N$.
30+
31+
The time complexity is $O(\log n)$, where $n$ is the size of $N$. The space complexity is $O(1)$.
32+
2733
<!-- tabs:start -->
2834

2935
### **Python3**

lcci/05.02.Binary Number to String/README_EN.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# [05.02. Binary Number to String](https://leetcode.cn/problems/bianry-number-to-string-lcci)
1+
# [05.02. Binary Number to String](https://leetcode.cn/problems/binary-number-to-string-lcci)
22

33
[中文文档](/lcci/05.02.Binary%20Number%20to%20String/README.md)
44

@@ -30,6 +30,29 @@
3030

3131
## Solutions
3232

33+
**Solution 1: Decimal Fraction to Binary Fraction**
34+
35+
The method of converting a decimal fraction to a binary fraction is as follows: multiply the decimal part by $2$, take the integer part as the next digit of the binary fraction, and take the decimal part as the multiplicand for the next multiplication, until the decimal part is $0$ or the length of the binary fraction exceeds $32$ bits.
36+
37+
Let's take an example, suppose we want to convert $0.8125$ to a binary fraction, the process is as follows:
38+
39+
$$
40+
\begin{aligned}
41+
0.8125 \times 2 &= 1.625 \quad \text{take the integer part} \quad 1 \\
42+
0.625 \times 2 &= 1.25 \quad \text{take the integer part} \quad 1 \\
43+
0.25 \times 2 &= 0.5 \quad \text{take the integer part} \quad 0 \\
44+
0.5 \times 2 &= 1 \quad \text{take the integer part} \quad 1 \\
45+
\end{aligned}
46+
$$
47+
48+
So the binary fraction representation of the decimal fraction $0.8125$ is $0.1101_{(2)}$.
49+
50+
For this problem, since the real number is between $0$ and $1$, its integer part must be $0$. We only need to convert the decimal part into a binary fraction according to the above method. Stop the conversion when the decimal part is $0$ or the length of the binary fraction is not less than $32$ bits.
51+
52+
Finally, if the decimal part is not $0$, it means that the real number cannot be represented in binary within $32$ bits, return the string `"ERROR"`. Otherwise, return the converted binary fraction.
53+
54+
The time complexity is $O(C)$, and the space complexity is $O(C)$. Here, $C$ is the length of the binary fraction, with a maximum of $32$.
55+
3356
<!-- tabs:start -->
3457

3558
### **Python3**

lcci/05.03.Reverse Bits/README_EN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424

2525
## Solutions
2626

27+
**Solution 1: Two Pointers**
28+
29+
We can use two pointers $i$ and $j$ to maintain a sliding window, where $i$ is the right pointer and $j$ is the left pointer. Each time the right pointer $i$ moves one bit to the right, if the number of $0$s in the window exceeds $1$, then the left pointer $j$ moves one bit to the right, until the number of $0$s in the window does not exceed $1$. Then calculate the length of the window at this time, compare it with the current maximum length, and take the larger value as the current maximum length.
30+
31+
Finally, return the maximum length.
32+
33+
The time complexity is $O(\log M)$, and the space complexity is $O(1)$. Here, $M$ is the maximum value of a 32-bit integer.
34+
2735
<!-- tabs:start -->
2836

2937
### **Python3**

lcci/05.04.Closed Number/README_EN.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@
2929

3030
## Solutions
3131

32+
**Solution 1: Bit Manipulation**
33+
34+
First, let's consider how to find the first number that is larger than $num$ and has the same number of $1$s in its binary representation.
35+
36+
We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $1$ and the adjacent higher bit is $0$, then we have found a position where we can change the $0$ at this position to $1$ and change the $1$ at this position to $0$. Then we move all the remaining lower bits of $1$ to the lowest bit, so we get a number that is larger than $num$ and has the same number of $1$s in its binary representation.
37+
38+
Similarly, we can find the first number that is smaller than $num$ and has the same number of $1$s in its binary representation.
39+
40+
We can traverse the adjacent two binary bits of $num$ from low to high. If the lower bit is $0$ and the adjacent higher bit is $1$, then we have found a position where we can change the $1$ at this position to $0$ and change the $0$ at this position to $1$. Then we move all the remaining lower bits of $0$ to the lowest bit, so we get a number that is smaller than $num$ and has the same number of $1$s in its binary representation.
41+
42+
In implementation, we can use a piece of code to handle the above two situations uniformly.
43+
44+
The time complexity is $O(\log n)$, where $n$ is the size of $num$. The space complexity is $O(1)$.
45+
3246
<!-- tabs:start -->
3347

3448
### **Python3**

lcci/05.06.Convert Integer/README_EN.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646

4747
## Solutions
4848

49+
**Solution 1: Bit Manipulation**
50+
51+
We perform a bitwise XOR operation on A and B. The number of $1$s in the result is the number of bits that need to be changed.
52+
53+
The time complexity is $O(\log n)$, where $n$ is the maximum value of A and B. The space complexity is $O(1)$.
54+
4955
<!-- tabs:start -->
5056

5157
### **Python3**

lcci/08.01.Three Steps Problem/README_EN.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,42 @@
3232

3333
## Solutions
3434

35+
**Solution 1: Recursion**
36+
37+
We define $f[i]$ as the number of ways to reach the $i$-th step, initially $f[1]=1$, $f[2]=2$, $f[3]=4$. The answer is $f[n]$.
38+
39+
The recursion formula is $f[i] = f[i-1] + f[i-2] + f[i-3]$.
40+
41+
Since $f[i]$ is only related to $f[i-1]$, $f[i-2]$, $f[i-3]$, we can use three variables $a$, $b$, $c$ to store the values of $f[i-1]$, $f[i-2]$, $f[i-3]$, reducing the space complexity to $O(1)$.
42+
43+
The time complexity is $O(n)$, where $n$ is the given integer. The space complexity is $O(1)$.
44+
45+
**Solution 2: Matrix Quick Power to Accelerate Recursion**
46+
47+
We set $F(n)$ to represent a $1 \times 3$ matrix $\begin{bmatrix} F_{n - 1} & F_{n - 2} & F_{n - 3} \end{bmatrix}$, where $F_{n - 1}$, $F_{n - 2}$ and $F_{n - 3}$ respectively represent the number of ways to reach the $n - 1$-th, $n - 2$-th and $n - 3$-th steps.
48+
49+
We hope to derive $F(n)$ based on $F(n-1) = \begin{bmatrix} F_{n - 2} & F_{n - 3} & F_{n - 4} \end{bmatrix}$. That is to say, we need a matrix $base$, so that $F(n - 1) \times base = F(n)$, i.e.:
50+
51+
$$
52+
\begin{bmatrix}
53+
F_{n - 2} & F_{n - 3} & F_{n - 4}
54+
\end{bmatrix} \times base = \begin{bmatrix} F_{n - 1} & F_{n - 2} & F_{n - 3} \end{bmatrix}
55+
$$
56+
57+
Since $F_n = F_{n - 1} + F_{n - 2} + F_{n - 3}$, the matrix $base$ is:
58+
59+
$$
60+
\begin{bmatrix}
61+
1 & 1 & 0 \\
62+
1 & 0 & 1 \\
63+
1 & 0 & 0
64+
\end{bmatrix}
65+
$$
66+
67+
We define the initial matrix $res = \begin{bmatrix} 1 & 1 & 0 \end{bmatrix}$, then $F_n$ equals the sum of all elements in the result matrix of $res$ multiplied by $base^{n - 4}$. It can be solved using matrix quick power.
68+
69+
The time complexity is $O(\log n)$, and the space complexity is $O(1)$.
70+
3571
<!-- tabs:start -->
3672

3773
### **Python3**

lcci/08.02.Robot in a Grid/README_EN.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232

3333
## Solutions
3434

35+
**Solution 1: DFS (Depth-First Search)**
36+
37+
We can use depth-first search to solve this problem. We start from the top left corner and move right or down until we reach the bottom right corner. If at some step, we find that the current position is an obstacle, or the current position is already in the path, then we return. Otherwise, we add the current position to the path and mark the current position as visited, then continue to move right or down.
38+
39+
If we can finally reach the bottom right corner, then we have found a feasible path, otherwise, it means there is no feasible path.
40+
41+
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the number of rows and columns of the grid, respectively.
42+
3543
<!-- tabs:start -->
3644

3745
### **Python3**

lcci/08.04.Power Set/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@
3535

3636
当前枚举到的元素下标为 $u$,我们可以选择将其加入子集 $t$ 中,也可以选择不加入子集 $t$ 中。递归这两种选择,即可得到所有的子集。
3737

38-
时间复杂度 $O(n\times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。数组中每个元素有两种状态,即选择或不选择,共 $2^n$ 种状态,每种状态需要 $O(n)$ 的时间来构造子集。
38+
时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。数组中每个元素有两种状态,即选择或不选择,共 $2^n$ 种状态,每种状态需要 $O(n)$ 的时间来构造子集。
3939

4040
**方法二:二进制枚举**
4141

4242
我们可以将方法一中的递归过程改写成迭代的形式,即使用二进制枚举的方法来枚举所有的子集。
4343

4444
我们可以使用 $2^n$ 个二进制数来表示 $n$ 个元素的所有子集,若某个二进制数 `mask` 的第 $i$ 位为 $1$,表示子集中包含数组第 $i$ 个元素 $v$;若为 $0$,表示子集中不包含数组第 $i$ 个元素 $v$。
4545

46-
时间复杂度 $O(n\times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。一共有 $2^n$ 个子集,每个子集需要 $O(n)$ 的时间来构造。
46+
时间复杂度 $O(n \times 2^n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。一共有 $2^n$ 个子集,每个子集需要 $O(n)$ 的时间来构造。
4747

4848
<!-- tabs:start -->
4949

lcci/08.04.Power Set/README_EN.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,21 @@
4040

4141
## Solutions
4242

43-
Backtracking
43+
**Solution 1: Recursive Enumeration**
44+
45+
We design a recursive function $dfs(u, t)$, where $u$ is the index of the current element being enumerated, and $t$ is the current subset.
46+
47+
For the current element with index $u$, we can choose to add it to the subset $t$, or we can choose not to add it to the subset $t$. Recursively making these two choices will yield all subsets.
48+
49+
The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. Each element in the array has two states, namely chosen or not chosen, for a total of $2^n$ states. Each state requires $O(n)$ time to construct the subset.
50+
51+
**Solution 2: Binary Enumeration**
52+
53+
We can rewrite the recursive process in Method 1 into an iterative form, that is, using binary enumeration to enumerate all subsets.
54+
55+
We can use $2^n$ binary numbers to represent all subsets of $n$ elements. If the $i$-th bit of a binary number `mask` is $1$, it means that the subset contains the $i$-th element $v$ of the array; if it is $0$, it means that the subset does not contain the $i$-th element $v$ of the array.
56+
57+
The time complexity is $O(n \times 2^n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. There are a total of $2^n$ subsets, and each subset requires $O(n)$ time to construct.
4458

4559
<!-- tabs:start -->
4660

0 commit comments

Comments
 (0)