Skip to content

Commit 69fa9dc

Browse files
committed
更新 04. 基础算法篇 相关图片、图片标题
1 parent 3fe4247 commit 69fa9dc

27 files changed

+36
-36
lines changed

docs/ch04/04.02/04.02.01-Recursive-Algorithm.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
举个简单的例子来了解一下递归算法。比如阶乘的计算方法在数学上的定义为:
88

9-
$fact(n) = \begin{cases} 1 & \text{n = 0} \cr n * fact(n - 1) & \text{n > 0} \end{cases}$
9+
$fact(n) = \begin{cases} 1 & \text{n = 0} \cr n \times fact(n - 1) & \text{n > 0} \end{cases}$
1010

1111
根据阶乘计算方法的数学定义,我们可以使用调用函数自身的方式来实现阶乘函数 $fact(n)$ ,其实现代码可以写作:
1212

@@ -41,8 +41,8 @@ fact(6)
4141
1. 函数从 $fact(6)$ 开始,一层层地调用 $fact(5)$、$fact(4)$、…… 一直调用到最底层的 $fact(0)$。
4242
2. 当 $n == 0$ 时,$fact(0)$ 不再继续调用自身,而是直接向上一层返回结果 $1$。
4343
3. $fact(1)$ 通过下一层 $fact(0)$ 的计算结果得出 $fact(1) = 1 \times 1 = 1$,从而向上一层返回结果 $1$。
44-
4. $fact(2)$ 通过下一层 $fact(1)$ 的计算结果得出 $fact(2) = 2 \times 1 = 2$,从而向上一层返回结果 $2$。
45-
5. $fact(3)$ 通过下一层 $fact(2)$ 的计算结果得出 $fact(3) = 3 \times 2 = 6$,从而向上一层返回结果 $6$。
44+
4. $fact(2)$ 通过下一层 $fact(1)$ 的计算结果得出 $fact(2) = 2 \times 1 = 2 $,从而向上一层返回结果 $2$。
45+
5. $fact(3)$ 通过下一层 $fact(2)$ 的计算结果得出 $fact(3) = 3 \times 2 = 6 $,从而向上一层返回结果 $6$。
4646
6. $fact(4)$ 通过下一层 $fact(3)$ 的计算结果得出 $fact(4) = 4 \times 6 = 24$,从而向上一层返回结果 $24$。
4747
7. $fact(5)$ 通过下一层 $fact(4)$ 的计算结果得出 $fact(5) = 5 \times 24 = 120$,从而向上一层返回结果 $120$。
4848
8. $fact(6)$ 通过下一层 $fact(5)$ 的计算结果得出 $fact(6) = 6 \times 120 = 720$,从而返回函数的最终结果 $720$。
@@ -56,9 +56,9 @@ fact(6)
5656

5757
这两个部分也可以叫做「递推过程」和「回归过程」,如下面两幅图所示:
5858

59-
![](../../images/20220407160648.png)
59+
![递推过程](../../images/20220407160648.png)
6060

61-
![](../../images/20220407160659.png)
61+
![回归过程](../../images/20220407160659.png)
6262

6363
如上面所说,我们可以把「递归」分为两个部分:「递推过程」和「回归过程」。
6464

@@ -177,7 +177,7 @@ $f(n) = \begin{cases} 0 & n = 0 \cr 1 & n = 1 \cr f(n - 2) + f(n - 1) & n > 1 \e
177177

178178
其对应的递归过程如下图所示:
179179

180-
![](../../images/20230307164107.png)
180+
![斐波那契数列的递归过程](../../images/20230307164107.png)
181181

182182
从图中可以看出:想要计算 $f(5)$,需要先计算 $f(3)$ 和 $f(4)$,而在计算 $f(4)$ 时还需要计算 $f(3)$,这样 $f(3)$ 就进行了多次计算。同理 $f(0)$、$f(1)$、$f(2)$ 都进行了多次计算,就导致了重复计算问题。
183183

@@ -327,4 +327,4 @@ class Solution:
327327
- 【博文】[递归 & 分治 - OI Wiki](https://oi-wiki.org/basic/divide-and-conquer/)
328328
- 【博文】[递归详解 - labuladong](https://github.com/labuladong/fucking-algorithm/blob/master/算法思维系列/递归详解.md)
329329
- 【博文】[递归 - 数据结构与算法之美 - 极客时间](https://time.geekbang.org/column/article/41440)
330-
- 【视频】[清华学长带你从宏观角度看递归](https://mp.weixin.qq.com/s/BHY7ZBxIr3UCpIvY4-IVOQ)
330+
- 【视频】[清华学长带你从宏观角度看递归](https://mp.weixin.qq.com/s/BHY7ZBxIr3UCpIvY4-IVOQ)

docs/ch04/04.02/04.02.05-Divide-And-Conquer-Algorithm.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
简单来说,分治算法的基本思想就是: **把规模大的问题不断分解为子问题,使得问题规模减小到可以直接求解为止。**
1010

11-
![](../../images/20220413153059.png)
11+
![分治算法的基本思想](../../images/20220413153059.png)
1212

1313
### 1.2 分治算法和递归算法的异同
1414

@@ -18,7 +18,7 @@
1818

1919
分治算法从实现方式上来划分,可以分为两种:「递归算法」和「迭代算法」。
2020

21-
![](../../images/20220414093828.png)
21+
![分治算法的实现方式](../../images/20240513162133.png)
2222

2323
一般情况下,分治算法比较适合使用递归算法来实现。但除了递归算法之外,分治算法还可以通过迭代算法来实现。比较常见的例子有:快速傅里叶变换算法、二分查找算法、非递归实现的归并排序算法等等。
2424

@@ -70,7 +70,7 @@ def divide_and_conquer(problems_n): # problems_n 为问题规模
7070

7171
一般来讲,分治算法将一个问题划分为 $a$ 个形式相同的子问题,每个子问题的规模为 $n/b$,则总的时间复杂度的递归表达式可以表示为:
7272

73-
$T(n) = \begin{cases} \begin{array} \ \Theta{(1)} & n = 1 \cr a \times T(n/b) + f(n) & n > 1 \end{array} \end{cases}$
73+
$T(n) = \begin{cases} \Theta{(1)} & n = 1 \cr a \times T(n/b) + f(n) & n > 1 \end{cases}$
7474

7575
其中,每次分解时产生的子问题个数是 $a$ ,每个子问题的规模是原问题规模的 $1 / b$,分解和合并 $a$ 个子问题的时间复杂度是 $f(n)$。
7676

@@ -84,15 +84,15 @@ $T(n) = \begin{cases} \begin{array} \ \Theta{(1)} & n = 1 \cr a \times T(n/b) +
8484

8585
我们得出归并排序算法的递归表达式如下:
8686

87-
$T(n) = \begin{cases} \begin{array} \ O{(1)} & n = 1 \cr 2 \times T(n/2) + O(n) & n > 1 \end{array} \end{cases}$
87+
$T(n) = \begin{cases} O{(1)} & n = 1 \cr 2 \times T(n/2) + O(n) & n > 1 \end{cases}$
8888

8989
根据归并排序的递归表达式,当 $n > 1$ 时,可以递推求解:
9090

91-
$\begin{align} T(n) & = 2 \times T(n/2) + O(n) \cr & = 2 \times (2 \times T(n / 4) + O(n/2)) + O(n) \cr & = 4 \times T(n/4) + 2 \times O(n) \cr & = 8 \times T(n/8) + 3 \times O(n) \cr & = …… \cr & = 2^x \times T(n/2^x) + x \times O(n) \end{align}$
91+
$$\begin{aligned} T(n) & = 2 \times T(n/2) + O(n) \cr & = 2 \times (2 \times T(n / 4) + O(n/2)) + O(n) \cr & = 4 \times T(n/4) + 2 \times O(n) \cr & = 8 \times T(n/8) + 3 \times O(n) \cr & = …… \cr & = 2^x \times T(n/2^x) + x \times O(n) \end{aligned}$$
9292

9393
递推最终规模为 $1$,令 $n = 2^x$,则 $x = \log_2n$,则:
9494

95-
$\begin{align} T(n) & = n \times T(1) + \log_2n \times O(n) \cr & = n + \log_2n \times O(n) \cr & = O(n \times \log_2n) \end{align}$
95+
$$\begin{aligned} T(n) & = n \times T(1) + \log_2n \times O(n) \cr & = n + \log_2n \times O(n) \cr & = O(n \times \log_2n) \end{aligned}$$
9696

9797
则归并排序的时间复杂度为 $O(n \times \log_2n)$。
9898

@@ -108,13 +108,13 @@ $\text{时间复杂度} = \text{叶子数} \times T(1) + \text{成本和} = 2^x
108108

109109
归并排序算法的递归表达式如下:
110110

111-
$T(n) = \begin{cases} \begin{array} \ O{(1)} & n = 1 \cr 2T(n/2) + O(n) & n > 1 \end{array} \end{cases}$
111+
$T(n) = \begin{cases} O{(1)} & n = 1 \cr 2T(n/2) + O(n) & n > 1 \end{cases}$
112112

113113
其对应的递归树如下图所示。
114114

115-
![](../../images/20220414171458.png)
115+
![归并排序算法的递归树](../../images/20220414171458.png)
116116

117-
因为 $n = 2^x$,则 $x = \log_2n$,则归并排序算法的时间复杂度为:$2^x \times T(1) + x \times O(n) = n + \log_2n \times O(n) = O(n \times log_2n)$。
117+
因为 $n = 2^x$,则 $x = \log_2n$,则归并排序算法的时间复杂度为:$2^x \times T(1) + x \times O(n) = n + \log_2n \times O(n) = O(n \times \log_2n)$。
118118

119119
## 4. 分治算法的应用
120120

@@ -152,7 +152,7 @@ $T(n) = \begin{cases} \begin{array} \ O{(1)} & n = 1 \cr 2T(n/2) + O(n) & n > 1
152152

153153
使用归并排序算法对数组排序的过程如下图所示。
154154

155-
![](../../images/20220414204405.png)
155+
![归并排序算法对数组排序的过程](../../images/20220414204405.png)
156156

157157
#### 4.1.4 代码
158158

@@ -223,7 +223,7 @@ class Solution:
223223

224224
二分查找的的分治算法过程如下图所示。
225225

226-
![](../../images/20211223115032.png)
226+
![二分查找的的分治算法过程](../../images/20211223115032.png)
227227

228228
#### 4.2.4 代码
229229

@@ -257,4 +257,4 @@ class Solution:
257257
- 【博文】[从合并排序算法看“分治法” - 船长&CAP - 博客园](https://www.cnblogs.com/liuning8023/archive/2012/06/25/2562747.html)
258258
- 【博文】[递归、迭代、分治、回溯、动态规划、贪心算法 - 力扣](https://leetcode.cn/circle/article/yXFal5/)
259259
- 【博文】[递归 & 分治 - OI Wiki](https://oi-wiki.org/basic/divide-and-conquer/)
260-
- 【博文】[漫画:5分钟弄懂分治算法!它和递归算法的关系!](https://mp.weixin.qq.com/s/0Z1tiqWTO410jYTJ4K0Ihg)
260+
- 【博文】[漫画:5分钟弄懂分治算法!它和递归算法的关系!](https://mp.weixin.qq.com/s/0Z1tiqWTO410jYTJ4K0Ihg)

docs/ch04/04.03/04.03.01-Backtracking-Algorithm.md

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

3636
对于上述决策过程,我们也可以用一棵决策树来表示:
3737

38-
![](../../images/20220425102048.png)
38+
![全排列问题的决策树](../../images/20220425102048.png)
3939

4040
从全排列的决策树中我们可以看出:
4141

@@ -207,7 +207,7 @@ for i in range(len(nums)): # 枚举可选元素列表
207207

208208
1. **明确所有选择**:根据数组中每个位置上的元素选与不选两种选择,画出决策树,如下图所示。
209209

210-
- ![](../../images/20220425210640.png)
210+
- ![子集的决策树](../../images/20220425210640.png)
211211

212212
2. **明确终止条件**
213213

@@ -305,7 +305,7 @@ class Solution:
305305

306306
1. **明确所有选择**:根据棋盘中当前行的所有列位置上是否选择放置皇后,画出决策树,如下图所示。
307307

308-
- ![](../../images/20220426095225.png)
308+
- ![n 皇后问题的决策树](../../images/20220426095225.png)
309309

310310
2. **明确终止条件**
311311

@@ -417,4 +417,4 @@ class Solution:
417417
- 【题解】[「代码随想录」带你学透回溯算法!51. N-Queens - N 皇后 - 力扣](https://leetcode.cn/problems/n-queens/solution/dai-ma-sui-xiang-lu-51-n-queenshui-su-fa-2k32/)
418418
- 【文章】[回溯算法详解](https://mp.weixin.qq.com/s/trILKSiN9EoS58pXmvUtUQ)
419419
- 【文章】[回溯算法详解修订版 - labuladong](https://github.com/labuladong/fucking-algorithm/blob/master/算法思维系列/回溯算法详解修订版.md)
420-
- 【文章】[【算法】回溯法四步走 - Nemo& - 博客园](https://www.cnblogs.com/blknemo/p/12431911.html)
420+
- 【文章】[【算法】回溯法四步走 - Nemo& - 博客园](https://www.cnblogs.com/blknemo/p/12431911.html)

docs/ch04/04.04/04.04.01-Greedy-Algorithm.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
2626
换句话说,当进行选择时,我们直接做出在当前问题中看来最优的选择,而不用去考虑子问题的解。在做出选择之后,才会去求解剩下的子问题,如下图所示。
2727

28-
![](../../images/20220511174939.png)
28+
![贪心选择性质](../../images/20240513163300.png)
2929

3030
贪心算法在进行选择时,可能会依赖之前做出的选择,但不会依赖任何将来的选择或是子问题的解。运用贪心算法解决的问题在程序的运行过程中无回溯过程。
3131

@@ -39,7 +39,7 @@
3939

4040
也就是说,如果原问题的最优解包含子问题的最优解,则说明该问题满足最优子结构性质。
4141

42-
![](../../images/20220511175042.png)
42+
![最优子结构性质](../../images/20240513163310.png)
4343

4444
在做了贪心选择后,满足最优子结构性质的原问题可以分解成规模更小的类似子问题来解决,并且可以通过贪心选择和子问题的最优解推导出问题的最优解。
4545

@@ -84,8 +84,8 @@
8484

8585
**说明**
8686

87-
- $1 \le g.length \le 3 \times 10^4$。
88-
- $0 \le s.length \le 3 \times 10^4$。
87+
- $1 \le g.length \le 3 * 10^4$。
88+
- $0 \le s.length \le 3 * 10^4$。
8989
- $1 \le g[i], s[j] \le 2^{31} - 1$。
9090

9191
**示例**

docs/ch04/04.05/04.05.01-Bit-Operation.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
在学习二进制数的位运算之前,我们先来了解一下什么叫做「二进制数」。
1010

11-
![](../../images/20230225233101.png)
11+
![二进制数](../../images/202405132135165.png)
1212

1313
> **二进制数(Binary)**:由 $0$ 和 $1$ 两个数码来表示的数。二进制数中每一个 $0$ 或每一个 $1$ 都称为一个「位(Bit)」。
1414
@@ -31,7 +31,7 @@
3131

3232
同理,在二进制数中,$01101010_{(2)}$ 可以看作为 $(0 \times 2^7) + (1 \times 2^6) + (1 \times 2^5) + (0 \times 2^4) + (1 \times 2^3) + (0 \times 2^2) + (1 \times 2^1) + (0 \times 2^0)$,即 $0 + 64 + 32 + 0 + 8 + 0 + 2 + 0 = 106_{(10)}$。
3333

34-
![](../../images/20230225233152.png)
34+
![二进制数转十进制数](../../images/202405132136456.png)
3535

3636
我们可以通过这样的方式,将一个二进制数转为十进制数。
3737

@@ -84,7 +84,7 @@ $\begin{aligned} 106 \div 2 = 53 & \text{(余 0)} \cr 53 \div 2 = 26 & \text
8484

8585
举个例子,对二进制数 $01111100_{(2)}$ 与 $00111110_{(2)}$ 进行按位与运算,结果为 $00111100_{(2)}$,如图所示:
8686

87-
![](../../images/20230225233202.png)
87+
![按位与运算](../../images/202405132137023.png)
8888

8989
### 2.2 按位或运算
9090

@@ -99,7 +99,7 @@ $\begin{aligned} 106 \div 2 = 53 & \text{(余 0)} \cr 53 \div 2 = 26 & \text
9999

100100
举个例子,对二进制数 $01001010_{(2)}$ 与 $01011011_{(2)}$ 进行按位或运算,结果为 $01011011_{(2)}$,如图所示:
101101

102-
![](../../images/20230225233231.png)
102+
![按位或运算](../../images/202405132137593.png)
103103

104104
### 2.3 按位异或运算
105105

@@ -117,7 +117,7 @@ $\begin{aligned} 106 \div 2 = 53 & \text{(余 0)} \cr 53 \div 2 = 26 & \text
117117

118118
举个例子,对二进制数 $01001010_{(2)}$ 与 $01000101_{(2)}$ 进行按位异或运算,结果为 $00001111_{(2)}$,如图所示:
119119

120-
![](../../images/20230225233240.png)
120+
![按位异或运算](../../images/202405132137874.png)
121121

122122
### 2.4 取反运算
123123

@@ -129,21 +129,21 @@ $\begin{aligned} 106 \div 2 = 53 & \text{(余 0)} \cr 53 \div 2 = 26 & \text
129129

130130
举个例子,对二进制数 $01101010_{(2)}$ 进行取反运算,结果如图所示:
131131

132-
![](../../images/20230225233257.png)
132+
![取反运算](../../images/202405132138853.png)
133133

134134
### 2.5 左移运算和右移运算
135135

136136
> **左移运算(SHL)**: 左移运算符为 `<<`。其功能是对一个二进制数的各个二进位全部左移若干位(高位丢弃,低位补 $0$)。
137137
138138
举个例子,对二进制数 $01101010_{(2)}$ 进行左移 $1$ 位运算,结果为 $11010100_{(2)}$,如图所示:
139139

140-
![](../../images/20230225233308.png)
140+
![左移运算](../../images/202405132138841.png)
141141

142142
> **右移运算(SHR)**: 右移运算符为 `>>`。其功能是对一个二进制数的各个二进位全部右移若干位(低位丢弃,高位补 $0$)。
143143
144144
举个例子,对二进制数 $01101010_{(2)}$ 进行右移 $1$ 位运算,结果为 $00110101_{(2)}$,如图所示:
145145

146-
![](../../images/20230225233317.png)
146+
![右移运算](../../images/202405132138348.png)
147147

148148
## 3. 位运算的应用
149149

@@ -317,4 +317,4 @@ class Solution:
317317
- 【博文】[Python 中的按位运算符 |【生长吧!Python!】- 云社区 - 华为云](https://bbs.huaweicloud.com/blogs/280901)
318318
- 【博文】[一文读懂位运算的使用 - 小黑说 Java - 掘金](https://juejin.cn/post/7011407264581943326)
319319
- 【博文】[枚举排列和枚举子集 - CUC ACM-Wiki](https://cuccs.github.io/acm-wiki/search/enumeration/)
320-
- 【博文】[Swift 运算符 | 菜鸟教程](https://www.runoob.com/swift/swift-operators.html)
320+
- 【博文】[Swift 运算符 | 菜鸟教程](https://www.runoob.com/swift/swift-operators.html)

docs/images/20220414093828.png

-13.4 KB
Binary file not shown.

docs/images/20220511174939.png

-7.82 KB
Binary file not shown.

docs/images/20220511175042.png

-9.21 KB
Binary file not shown.

docs/images/20230225233101.png

-1.96 KB
Binary file not shown.

docs/images/20230225233152.png

-4.63 KB
Binary file not shown.

0 commit comments

Comments
 (0)