Skip to content

Commit 52e3917

Browse files
committed
feat: add solutions to lcci problems
* No.10.11.Peaks and Valleys * No.16.01.Swap Numbers * No.16.02.Words Frequency * No.16.05.Factorial Zeros * No.16.07.Maximum * No.16.11.Diving Board * No.16.14.Best Line * No.16.15.Master Mind * No.16.16.Sub Sort * No.16.17.Contiguous Sequence * No.16.18.Pattern Matching * No.16.19.Pond Sizes * No.16.20.T9 * No.16.21.Sum Swap * No.16.22.Langtons Ant * No.16.24.Pairs With Sum
1 parent 74cd4f5 commit 52e3917

File tree

29 files changed

+362
-287
lines changed

29 files changed

+362
-287
lines changed

lcci/10.11.Peaks and Valleys/README_EN.md

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020

2121
## Solutions
2222

23+
**Solution 1: Sorting**
24+
25+
We first sort the array, and then traverse the array and swap the elements at even indices with their next element.
26+
27+
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.
28+
2329
<!-- tabs:start -->
2430

2531
### **Python3**

lcci/16.01.Swap Numbers/README.md

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

2020
<!-- 这里可写通用的实现逻辑 -->
2121

22-
异或运算。
22+
**方法一:位运算**
23+
24+
我们可以使用异或运算 $\oplus$ 来实现两个数的交换。
25+
26+
异或运算有以下三个性质。
27+
28+
- 任何数和 $0$ 做异或运算,结果仍然是原来的数,即 $a \oplus 0=a$。
29+
- 任何数和其自身做异或运算,结果是 $0$,即 $a \oplus a=0$。
30+
- 异或运算满足交换律和结合律,即 $a \oplus b \oplus a=b \oplus a \oplus a=b \oplus (a \oplus a)=b \oplus 0=b$。
31+
32+
因此,我们可以对 $numbers$ 中的两个数 $a$ 和 $b$ 进行如下操作:
33+
34+
- $a=a \oplus b$,此时 $a$ 中存储了两个数的异或结果;
35+
- $b=a \oplus b$,此时 $b$ 中存储了原来 $a$ 的值;
36+
- $a=a \oplus b$,此时 $a$ 中存储了原来 $b$ 的值;
37+
38+
这样,我们就可以实现在不使用临时变量的情况下对两个数进行交换。
39+
40+
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
2341

2442
<!-- tabs:start -->
2543

lcci/16.01.Swap Numbers/README_EN.md

+20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,26 @@
2424

2525
## Solutions
2626

27+
**Solution 1: Bitwise Operation**
28+
29+
We can use the XOR operation $\oplus$ to implement the swap of two numbers.
30+
31+
The XOR operation has the following three properties:
32+
33+
- Any number XORed with $0$ remains unchanged, i.e., $a \oplus 0=a$.
34+
- Any number XORed with itself results in $0$, i.e., $a \oplus a=0$.
35+
- The XOR operation satisfies the commutative and associative laws, i.e., $a \oplus b \oplus a=b \oplus a \oplus a=b \oplus (a \oplus a)=b \oplus 0=b$.
36+
37+
Therefore, we can perform the following operations on two numbers $a$ and $b$ in the array $numbers$:
38+
39+
- $a=a \oplus b$, now $a$ stores the XOR result of the two numbers;
40+
- $b=a \oplus b$, now $b$ stores the original value of $a$;
41+
- $a=a \oplus b$, now $a$ stores the original value of $b$;
42+
43+
In this way, we can swap two numbers without using a temporary variable.
44+
45+
The time complexity is $O(1)$, and the space complexity is $O(1)$.
46+
2747
<!-- tabs:start -->
2848

2949
### **Python3**

lcci/16.02.Words Frequency/README.md

+10-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>设计一个方法,找出任意指定单词在一本书中的出现频率。</p>
910
<p>你的实现应该支持如下操作:</p>
1011
<ul>
@@ -33,9 +34,11 @@ wordsFrequency.get("pen"); //返回1
3334

3435
**方法一:哈希表**
3536

36-
我们用哈希表 `cnt` 统计每个单词出现的次数,`get` 函数直接返回 `cnt[word]` 即可。
37+
我们用哈希表 $cnt$ 统计 $book$ 中每个单词出现的次数。
38+
39+
调用 `get` 函数时,我们只需要返回 $cnt$ 中对应的单词的出现次数即可。
3740

38-
初始化哈希表 `cnt` 的时间复杂度为 $O(n)$,其中 $n$ 为 `book` 的长度。`get` 函数的时间复杂度为 $O(1)$。空间复杂度为 $O(n)$。
41+
时间复杂度方面,初始化哈希表 $cnt$ 的时间复杂度为 $O(n)$,其中 $n$ 为 $book$ 的长度。`get` 函数的时间复杂度为 $O(1)$。空间复杂度为 $O(n)$。
3942

4043
<!-- tabs:start -->
4144

@@ -194,7 +197,7 @@ class WordsFrequency {
194197
```rust
195198
use std::collections::HashMap;
196199
struct WordsFrequency {
197-
counter: HashMap<String, i32>
200+
cnt: HashMap<String, i32>
198201
}
199202

200203

@@ -205,15 +208,15 @@ struct WordsFrequency {
205208
impl WordsFrequency {
206209

207210
fn new(book: Vec<String>) -> Self {
208-
let mut counter = HashMap::new();
211+
let mut cnt = HashMap::new();
209212
for word in book.into_iter() {
210-
*counter.entry(word).or_insert(0) += 1;
213+
*cnt.entry(word).or_insert(0) += 1;
211214
}
212-
Self { counter }
215+
Self { cnt }
213216
}
214217

215218
fn get(&self, word: String) -> i32 {
216-
*self.counter.get(&word).unwrap_or(&0)
219+
*self.cnt.get(&word).unwrap_or(&0)
217220
}
218221
}
219222

lcci/16.02.Words Frequency/README_EN.md

+13-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ wordsFrequency.get(&quot;pen&quot;); //returns 1
4242

4343
## Solutions
4444

45+
**Solution 1: Hash Table**
46+
47+
We use a hash table $cnt$ to count the number of occurrences of each word in $book$.
48+
49+
When calling the `get` function, we only need to return the number of occurrences of the corresponding word in $cnt$.
50+
51+
In terms of time complexity, the time complexity of initializing the hash table $cnt$ is $O(n)$, where $n$ is the length of $book$. The time complexity of the `get` function is $O(1)$. The space complexity is $O(n)$.
52+
4553
<!-- tabs:start -->
4654

4755
### **Python3**
@@ -195,7 +203,7 @@ class WordsFrequency {
195203
```rust
196204
use std::collections::HashMap;
197205
struct WordsFrequency {
198-
counter: HashMap<String, i32>
206+
cnt: HashMap<String, i32>
199207
}
200208

201209

@@ -206,15 +214,15 @@ struct WordsFrequency {
206214
impl WordsFrequency {
207215

208216
fn new(book: Vec<String>) -> Self {
209-
let mut counter = HashMap::new();
217+
let mut cnt = HashMap::new();
210218
for word in book.into_iter() {
211-
*counter.entry(word).or_insert(0) += 1;
219+
*cnt.entry(word).or_insert(0) += 1;
212220
}
213-
Self { counter }
221+
Self { cnt }
214222
}
215223

216224
fn get(&self, word: String) -> i32 {
217-
*self.counter.get(&word).unwrap_or(&0)
225+
*self.cnt.get(&word).unwrap_or(&0)
218226
}
219227
}
220228

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
class WordsFrequency:
2-
def __init__(self, book: List[str]):
3-
self.cnt = Counter(book)
4-
5-
def get(self, word: str) -> int:
6-
return self.cnt[word]
7-
8-
9-
# Your WordsFrequency object will be instantiated and called as such:
10-
# obj = WordsFrequency(book)
11-
# param_1 = obj.get(word)
1+
class WordsFrequency:
2+
def __init__(self, book: List[str]):
3+
self.cnt = Counter(book)
4+
5+
def get(self, word: str) -> int:
6+
return self.cnt[word]
7+
8+
9+
# Your WordsFrequency object will be instantiated and called as such:
10+
# obj = WordsFrequency(book)
11+
# param_1 = obj.get(word)
+29-29
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
use std::collections::HashMap;
2-
struct WordsFrequency {
3-
counter: HashMap<String, i32>
4-
}
5-
6-
7-
/**
8-
* `&self` means the method takes an immutable reference.
9-
* If you need a mutable reference, change it to `&mut self` instead.
10-
*/
11-
impl WordsFrequency {
12-
13-
fn new(book: Vec<String>) -> Self {
14-
let mut counter = HashMap::new();
15-
for word in book.into_iter() {
16-
*counter.entry(word).or_insert(0) += 1;
17-
}
18-
Self { counter }
19-
}
20-
21-
fn get(&self, word: String) -> i32 {
22-
*self.counter.get(&word).unwrap_or(&0)
23-
}
24-
}
25-
26-
/**
27-
* Your WordsFrequency object will be instantiated and called as such:
28-
* let obj = WordsFrequency::new(book);
29-
* let ret_1: i32 = obj.get(word);
1+
use std::collections::HashMap;
2+
struct WordsFrequency {
3+
cnt: HashMap<String, i32>
4+
}
5+
6+
7+
/**
8+
* `&self` means the method takes an immutable reference.
9+
* If you need a mutable reference, change it to `&mut self` instead.
10+
*/
11+
impl WordsFrequency {
12+
13+
fn new(book: Vec<String>) -> Self {
14+
let mut cnt = HashMap::new();
15+
for word in book.into_iter() {
16+
*cnt.entry(word).or_insert(0) += 1;
17+
}
18+
Self { cnt }
19+
}
20+
21+
fn get(&self, word: String) -> i32 {
22+
*self.cnt.get(&word).unwrap_or(&0)
23+
}
24+
}
25+
26+
/**
27+
* Your WordsFrequency object will be instantiated and called as such:
28+
* let obj = WordsFrequency::new(book);
29+
* let ret_1: i32 = obj.get(word);
3030
*/

lcci/16.05.Factorial Zeros/README_EN.md

+13
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@
2727

2828
## Solutions
2929

30+
**Solution 1: Mathematics**
31+
32+
The problem is actually asking for the number of factors of $5$ in $[1,n]$.
33+
34+
Let's take $130$ as an example:
35+
36+
1. Divide $130$ by $5$ for the first time, and get $26$, which means there are $26$ numbers containing a factor of $5$.
37+
2. Divide $26$ by $5$ for the second time, and get $5$, which means there are $5$ numbers containing a factor of $5^2$.
38+
3. Divide $5$ by $5$ for the third time, and get $1$, which means there is $1$ number containing a factor of $5^3$.
39+
4. Add up all the counts to get the total number of factors of $5$ in $[1,n]$.
40+
41+
The time complexity is $O(\log n)$, and the space complexity is $O(1)$.
42+
3043
<!-- tabs:start -->
3144

3245
### **Python3**

lcci/16.07.Maximum/README_EN.md

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616

1717
## Solutions
1818

19+
**Solution 1: Bitwise Operation**
20+
21+
We can extract the sign bit $k$ of $a-b$. If the sign bit is $1$, it means $a \lt b$; if the sign bit is $0$, it means $a \ge b$.
22+
23+
Then the final result is $a \times (k \oplus 1) + b \times k$.
24+
25+
The time complexity is $O(1)$, and the space complexity is $O(1)$.
26+
1927
<!-- tabs:start -->
2028

2129
### **Python3**

lcci/16.11.Diving Board/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为<code>shorter</code>,长度较长的木板长度为<code>longer</code>。你必须正好使用<code>k</code>块木板。编写一个方法,生成跳水板所有可能的长度。</p>
910
<p>返回的长度需要从小到大排列。</p>
1011
<p><strong>示例:</strong></p>
@@ -24,6 +25,16 @@ k = 3
2425

2526
<!-- 这里可写通用的实现逻辑 -->
2627

28+
**方法一:分类讨论**
29+
30+
如果 $k=0$,则不存在任何一种方案,我们可以直接返回空列表。
31+
32+
如果 $shorter=longer$,则我们只能使用长度为 $longer \times k$ 的木板,因此我们直接返回长度为 $longer \times k$ 的列表。
33+
34+
否则,我们可以使用长度为 $shorter \times (k-i) + longer \times i$ 的木板,其中 $0 \leq i \leq k$。我们在 $[0, k]$ 的范围内枚举 $i$,并计算对应的长度即可。对于不同的 $i$,我们不会得到相同的长度,这是因为,假如有 $0 \leq i \lt j \leq k$,那么两者长度差为 $shorter \times (k-i) + longer \times i - shorter \times (k-j) - longer \times j$,整理得到长度差 $(i - j) \times (longer - shorter) \lt 0$。因此,对于不同的 $i$,我们会得到不同的长度。
35+
36+
时间复杂度 $O(k)$,其中 $k$ 为木板数量。忽略答案的空间消耗,空间复杂度 $O(1)$。
37+
2738
<!-- tabs:start -->
2839

2940
### **Python3**

lcci/16.11.Diving Board/README_EN.md

+10
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ k = 3
3333

3434
## Solutions
3535

36+
**Solution 1: Case Analysis**
37+
38+
If $k=0$, there is no solution, and we can directly return an empty list.
39+
40+
If $shorter=longer$, we can only use a board with length $longer \times k$, so we directly return a list with length $longer \times k$.
41+
42+
Otherwise, we can use a board with length $shorter \times (k-i) + longer \times i$, where $0 \leq i \leq k$. We enumerate $i$ in the range $[0, k]$, and calculate the corresponding length. For different values of $i$, we will not get the same length, because if $0 \leq i \lt j \leq k$, then the difference in length is $(i - j) \times (longer - shorter) \lt 0$. Therefore, for different values of $i$, we will get different lengths.
43+
44+
The time complexity is $O(k)$, where $k$ is the number of boards. Ignoring the space consumption of the answer, the space complexity is $O(1)$.
45+
3646
<!-- tabs:start -->
3747

3848
### **Python3**

lcci/16.14.Best Line/README_EN.md

+12
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@
2424

2525
## Solutions
2626

27+
**Solution 1: Brute Force**
28+
29+
We can enumerate any two points $(x_1, y_1), (x_2, y_2)$, connect these two points into a line, and the number of points on this line is 2. Then we enumerate other points $(x_3, y_3)$, and determine whether they are on the same line. If they are, the number of points on the line increases by 1; otherwise, the number of points on the line remains the same. Find the maximum number of points on a line, and the corresponding smallest two point indices are the answer.
30+
31+
The time complexity is $O(n^3)$, and the space complexity is $O(1)$. Here, $n$ is the length of the array `points`.
32+
33+
**Solution 2: Enumeration + Hash Table**
34+
35+
We can enumerate a point $(x_1, y_1)$, store the slope of the line connecting $(x_1, y_1)$ and all other points $(x_2, y_2)$ in a hash table. Points with the same slope are on the same line, and the key of the hash table is the slope, and the value is the number of points on the line. Find the maximum value in the hash table, which is the answer. To avoid precision issues, we can reduce the slope $\frac{y_2 - y_1}{x_2 - x_1}$, and the reduction method is to find the greatest common divisor, and then divide the numerator and denominator by the greatest common divisor. The resulting numerator and denominator are used as the key of the hash table.
36+
37+
The time complexity is $O(n^2 \times \log m)$, and the space complexity is $O(n)$. Here, $n$ and $m$ are the length of the array `points` and the maximum difference between all horizontal and vertical coordinates in the array `points`, respectively.
38+
2739
<!-- tabs:start -->
2840

2941
### **Python3**

lcci/16.15.Master Mind/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
**方法一:哈希表**
2727

28-
同时遍历两个字符串,算出对应位置字符相同的个数,累加到 $x$ 中,然后将两个字符串出现的字符以及出现的次数分别记录在哈希表 `cnt1``cnt2` 中。
28+
同时遍历两个字符串,算出对应位置字符相同的个数,累加到 $x$ 中,然后将两个字符串出现的字符以及出现的次数分别记录在哈希表 $cnt1$$cnt2$ 中。
2929

3030
接着遍历两个哈希表,算出有多少共同出现的字符,累加到 $y$ 中。那么答案就是 $[x, y - x]$。
3131

lcci/16.15.Master Mind/README_EN.md

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828

2929
## Solutions
3030

31+
**Solution 1: Hash Table**
32+
33+
We simultaneously traverse both strings, count the number of corresponding characters that are the same, and accumulate them in $x$. Then we record the characters and their frequencies in both strings in hash tables $cnt1$ and $cnt2$, respectively.
34+
35+
Next, we traverse both hash tables, count the number of common characters, and accumulate them in $y$. The answer is then $[x, y - x]$.
36+
37+
The time complexity is $O(C)$, and the space complexity is $O(C)$. Here, $C=4$ for this problem.
38+
3139
<!-- tabs:start -->
3240

3341
### **Python3**

lcci/16.16.Sub Sort/README_EN.md

+10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121

2222
## Solutions
2323

24+
**Solution 1: Two Passes**
25+
26+
We first traverse the array $array$ from left to right, and use $mx$ to record the maximum value encountered so far. If the current value $x$ is less than $mx$, it means that $x$ needs to be sorted, and we record the index $i$ of $x$ as $right$; otherwise, update $mx$.
27+
28+
Similarly, we traverse the array $array$ from right to left, and use $mi$ to record the minimum value encountered so far. If the current value $x$ is greater than $mi$, it means that $x$ needs to be sorted, and we record the index $i$ of $x$ as $left$; otherwise, update $mi$.
29+
30+
Finally, return $[left, right]$.
31+
32+
The time complexity is $O(n)$, where $n$ is the length of the array $array$. The space complexity is $O(1)$.
33+
2434
<!-- tabs:start -->
2535

2636
### **Python3**

0 commit comments

Comments
 (0)