10
10
11
11
### 1.2 分治算法和递归算法的异同
12
12
13
- 从定义上来看,分治算法的思想和之前我们讲过的递归算法的思想是一样的 ,都是把规模大的问题不断分解为子问题。
13
+ 从定义上来看,分治算法的思想和递归算法的思想是一样的 ,都是把规模大的问题不断分解为子问题。
14
14
15
- 其实,分治算法和递归算法的关系是包含与被包含的关系,可以看做` 递归算法 ∈ 分治算法 ` 。
15
+ 其实,分治算法和递归算法的关系是包含与被包含的关系,可以看做: ` 递归算法 ∈ 分治算法 ` 。
16
16
17
17
分治算法从实现方式上来划分,可以分为两种:「递归算法」和「迭代算法」。
18
18
19
19
![ ] ( https://qcdn.itcharge.cn/images/20220414093828.png )
20
20
21
- 实际上, 分治算法一般都比较适合使用递归算法来实现。但除了递归算法之外,分治算法还可以通过迭代算法来实现。比较常见的例子有:快速傅里叶变换算法、二分查找算法、非递归实现的归并排序算法等等。
21
+ 分治算法一般都比较适合使用递归算法来实现。但除了递归算法之外,分治算法还可以通过迭代算法来实现。比较常见的例子有:快速傅里叶变换算法、二分查找算法、非递归实现的归并排序算法等等。
22
22
23
23
### 1.3 分治算法的适用条件
24
24
25
- 分治算法能够解决的问题,一般需要满足以下 ` 4 ` 个条件:
25
+ 分治算法能够解决的问题,一般需要满足以下 4ドル$ 个条件:
26
26
27
27
1 . 原问题可以分解为若干个规模较小的相同子问题。
28
28
2 . 分解出来的子问题可以独立求解,即子问题之间不包含公共的子子问题。
31
31
32
32
## 2. 分治算法的基本步骤
33
33
34
- 使用分治算法解决问题主要分为 ` 3 ` 个步骤:
34
+ 使用分治算法解决问题主要分为 3ドル$ 个步骤:
35
35
36
36
1 . ** 分解** :把要解决的问题分解为成若干个规模较小、相对独立、与原问题形式相同的子问题。
37
37
2 . ** 求解** :递归求解各个子问题。
38
38
3 . ** 合并** :按照原问题的要求,将子问题的解逐层合并构成原问题的解。
39
39
40
- 其中第 ` 1 ` 步中将问题分解为若干个子问题时,最好使子问题的规模大致相同。换句话说,将一个问题分成大小相等的 ` k ` 个子问题的处理方法是行之有效的。在许多问题中,可以取 ` k = s2 ` 。这种使子问题规模大致相等的做法是出自一种平衡子问题的思想,它几乎总是比子问题规模不等的做法要好。
40
+ 其中第 1ドル$ 步中将问题分解为若干个子问题时,最好使子问题的规模大致相同。换句话说,将一个问题分成大小相等的 $k$ 个子问题的处理方法是行之有效的。在许多问题中,可以取 $ k = 2$ 。这种使子问题规模大致相等的做法是出自一种平衡子问题的思想,它几乎总是比子问题规模不等的做法要好。
41
41
42
- 其中第 ` 2 ` 步的「递归求解各个子问题」指的是按照同样的分治策略进行求解,即通过将这些子问题分解为更小的子子问题来进行求解。就这样一直分解下去,直到分解出来的子问题简单到只用常数操作时间即可解决为止。
42
+ 其中第 2ドル$ 步的「递归求解各个子问题」指的是按照同样的分治策略进行求解,即通过将这些子问题分解为更小的子子问题来进行求解。就这样一直分解下去,直到分解出来的子问题简单到只用常数操作时间即可解决为止。
43
43
44
- 在完成第 ` 2 ` 步之后,最小子问题的解可用常数时间求得。然后我们再按照递归算法中回归过程的顺序,由底至上地将子问题的解合并起来,逐级上推就构成了原问题的解。
44
+ 在完成第 2ドル$ 步之后,最小子问题的解可用常数时间求得。然后我们再按照递归算法中回归过程的顺序,由底至上地将子问题的解合并起来,逐级上推就构成了原问题的解。
45
45
46
- 按照分而治之的策略,在编写分治算法的代码时,也是按照上面的 ` 3 ` 个步骤来编写的,其对应的伪代码如下:
46
+ 按照分而治之的策略,在编写分治算法的代码时,也是按照上面的 3ドル$ 个步骤来编写的,其对应的伪代码如下:
47
47
48
48
``` Python
49
49
def divide_and_conquer (problem ): # problem 为问题规模
@@ -142,8 +142,8 @@ $T(n) = \begin{cases} \begin{array} \ O{(1)} & n = 1 \cr 2T(n/2) + O(n) & n > 1
142
142
143
143
我们使用归并排序算法来解决这道题。
144
144
145
- 1 . ** 分解** :将待排序序列中的 ` n ` 个元素分解为左右两个各包含 ` n / 2 ` 个元素的子序列。
146
- 2 . ** 求解** :递归将子序列进行分解和排序,直到所有子序列长度为 ` 1 ` 。
145
+ 1 . ** 分解** :将待排序序列中的 $n$ 个元素分解为左右两个各包含 $\frac{n}{2}$ 个元素的子序列。
146
+ 2 . ** 求解** :递归将子序列进行分解和排序,直到所有子序列长度为 1ドル$ 。
147
147
3 . ** 合并** :把当前序列组中有序子序列逐层向上,进行两两合并。
148
148
149
149
使用归并排序算法对数组排序的过程如下图所示。
@@ -189,14 +189,14 @@ class Solution:
189
189
190
190
#### 4.2.2 题目大意
191
191
192
- ** 描述** :给定一个含有 ` n ` 个元素有序的(升序)整型数组 ` nums ` 和一个目标值 ` target ` 。
192
+ ** 描述** :给定一个含有 $n$ 个元素有序的(升序)整型数组 ` nums ` 和一个目标值 ` target ` 。
193
193
194
- ** 要求** :返回 ` target ` 在数组 ` nums ` 中的位置,如果找不到,则返回 ` -1 ` 。
194
+ ** 要求** :返回 ` target ` 在数组 ` nums ` 中的位置,如果找不到,则返回 $-1$ 。
195
195
196
196
** 说明** :
197
197
198
198
- 假设 ` nums ` 中的所有元素是不重复的。
199
- - ` n ` 将在 ` [1, 10000] ` 之间。
199
+ - $n$ 将在 $ [ 1, 10000] $ 之间。
200
200
- $-9999 \le nums[ i] \le 9999$。
201
201
202
202
** 示例** :
@@ -211,7 +211,7 @@ class Solution:
211
211
212
212
我们使用分治算法来解决这道题。与其他分治题目不一样的地方是二分查找不用进行合并过程,最小子问题的解就是原问题的解。
213
213
214
- 1 . ** 分解** :将数组的 ` n ` 个元素分解为左右两个各包含 ` n / 2 ` 个元素的子序列。
214
+ 1 . ** 分解** :将数组的 $n$ 个元素分解为左右两个各包含 $\frac{n}{2}$ 个元素的子序列。
215
215
2 . ** 求解** :取中间元素 ` nums[mid] ` 与 ` target ` 相比。
216
216
1 . 如果相等,则找到该元素;
217
217
2 . 如果 ` nums[mid] < target ` ,则递归在左子序列中进行二分查找。
0 commit comments