diff --git a/chapter_backtracking/backtracking_algorithm.md b/chapter_backtracking/backtracking_algorithm.md index e637a681a..3418fed83 100644 --- a/chapter_backtracking/backtracking_algorithm.md +++ b/chapter_backtracking/backtracking_algorithm.md @@ -8,7 +8,9 @@ comments: true 回溯算法通常采用「深度优先搜索」来遍历解空间。在二叉树章节中,我们提到前序、中序和后序遍历都属于深度优先搜索。下面,我们从二叉树的前序遍历入手,逐步了解回溯算法的工作原理。 -!!! question "例题一:在二叉树中搜索并返回所有值为 $7$ 的节点" +!!! question "例题一" + + 给定一个二叉树,搜索并记录所有值为 $7$ 的节点,返回节点列表。 **解题思路**:前序遍历这颗树,并判断当前节点的值是否为 $7$ ,若是则将该节点的值加入到结果列表 `res` 之中。 @@ -169,7 +171,9 @@ comments: true 值得说明的是,**回退并不等价于函数返回**。为解释这一点,我们对例题一稍作拓展。 -!!! question "在二叉树中搜索所有值为 $7$ 的节点,**返回根节点到这些节点的路径**" +!!! question "例题二" + + 在二叉树中搜索所有值为 $7$ 的节点,**返回根节点到这些节点的路径**。 **解题思路**:在例题一代码的基础上,我们需要借助一个列表 `path` 记录访问过的节点路径。当访问到值为 $7$ 的节点时,则复制 `path` 并添加进结果列表 `res` 。遍历完成后,`res` 中保存的就是所有的解。 @@ -393,7 +397,9 @@ comments: true 复杂的回溯问题通常包含一个或多个约束条件,**约束条件通常可用于“剪枝”**。 -!!! question "例题三:在二叉树中搜索所有值为 $7$ 的节点,返回根节点到这些节点的路径,**路径中不能包含值为 $3$ 的节点**" +!!! question "例题三" + + 在二叉树中搜索所有值为 $7$ 的节点,返回根节点到这些节点的路径,**路径中不能包含值为 $3$ 的节点**。 **解题思路**:在例题二的基础上添加剪枝操作,当遇到值为 $3$ 的节点时,则终止继续搜索。 diff --git a/chapter_backtracking/n_queens_problem.md b/chapter_backtracking/n_queens_problem.md index 5ffc9558d..3a8750857 100644 --- a/chapter_backtracking/n_queens_problem.md +++ b/chapter_backtracking/n_queens_problem.md @@ -4,7 +4,9 @@ comments: true # 12.3.   N 皇后问题 -!!! question "根据国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。给定 $n$ 个皇后和一个 $n \times n$ 大小的棋盘,寻找使得所有皇后之间无法相互攻击的摆放方案。" +!!! question + + 根据国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。给定 $n$ 个皇后和一个 $n \times n$ 大小的棋盘,寻找使得所有皇后之间无法相互攻击的摆放方案。 如下图所示,当 $n = 4$ 时,共可以找到两个解。从回溯算法的角度看,$n \times n$ 大小的棋盘共有 $n^2$ 个格子,给出了所有的选择 `choices` 。在逐个放置皇后的过程中,棋盘状态在不断地变化,每个时刻的棋盘就是状态 `state` 。 diff --git a/chapter_backtracking/permutations_problem.md b/chapter_backtracking/permutations_problem.md index 657fd272a..3898e5875 100644 --- a/chapter_backtracking/permutations_problem.md +++ b/chapter_backtracking/permutations_problem.md @@ -20,7 +20,9 @@ comments: true ## 12.2.1.   无重复的情况 -!!! question "输入一个整数数组,数组中不包含重复元素,返回所有可能的排列。" +!!! question + + 输入一个整数数组,数组中不包含重复元素,返回所有可能的排列。 **从回溯算法的角度看,我们可以把生成排列的过程想象成一系列选择的结果**。假设输入数组为 $[1, 2, 3]$ ,如果我们先选择 $1$ 、再选择 $3$ 、最后选择 $2$ ,则获得排列 $[1, 3, 2]$ 。回退表示撤销一个选择,之后继续尝试其他选择。 @@ -344,7 +346,9 @@ comments: true ## 12.2.2.   考虑重复的情况 -!!! question "输入一个整数数组,**数组中可能包含重复元素**,返回所有不重复的排列。" +!!! question + + 输入一个整数数组,**数组中可能包含重复元素**,返回所有不重复的排列。 假设输入数组为 $[1, 1, 2]$ 。为了方便区分两个重复的元素 $1$ ,接下来我们将第二个元素记为 $\hat{1}$ 。如下图所示,上述方法生成的排列有一半都是重复的。 diff --git a/chapter_searching/binary_search.md b/chapter_searching/binary_search.md index 0ccf54885..8ab3f9312 100755 --- a/chapter_searching/binary_search.md +++ b/chapter_searching/binary_search.md @@ -8,7 +8,9 @@ comments: true 我们先来求解一个简单的二分查找问题。 -!!! question "给定一个长度为 $n$ 的有序数组 `nums` ,元素按从小到大的顺序排列。查找并返回元素 `target` 在该数组中的索引。若数组中不包含该元素,则返回 $-1$ 。数组中不包含重复元素。" +!!! question + + 给定一个长度为 $n$ 的有序数组 `nums` ,元素按从小到大的顺序排列。请查找并返回元素 `target` 在该数组中的索引。若数组中不包含该元素,则返回 $-1$ 。数组中不包含重复元素。 该数组的索引范围可以使用区间 $[0, n - 1]$ 来表示。其中,**中括号表示“闭区间”,即包含边界值本身**。在该表示下,区间 $[i, j]$ 在 $i = j$ 时仍包含一个元素,在 $i > j$ 时为空区间。 diff --git a/chapter_searching/binary_search_edge.md b/chapter_searching/binary_search_edge.md index 8d5bd3235..61c3a2ff5 100644 --- a/chapter_searching/binary_search_edge.md +++ b/chapter_searching/binary_search_edge.md @@ -14,7 +14,9 @@ comments: true ## 10.2.1.   查找最左一个元素 -!!! question "查找并返回元素 `target` 在有序数组 `nums` 中首次出现的索引。若数组中不包含该元素,则返回 $-1$ 。数组可能包含重复元素。" +!!! question + + 给定一个长度为 $n$ 的有序数组 `nums` 。请查找并返回元素 `target` 在该数组中首次出现的索引。若数组中不包含该元素,则返回 $-1$ 。数组可能包含重复元素。 实际上,我们可以仅通过二分查找解决以上问题。方法的整体框架不变,先计算中点索引 `m` ,再判断 `target` 和 `nums[m]` 大小关系: @@ -104,11 +106,11 @@ comments: true while i <= j: m = (i + j) // 2 # 计算中点索引 m if nums[m] < target: - i = m + 1 # 此情况说明 target 在区间 [m+1, j] 中 + i = m + 1 # target 在区间 [m+1, j] 中 elif nums[m] > target: - j = m - 1 # 此情况说明 target 在区间 [i, m-1] 中 + j = m - 1 # target 在区间 [i, m-1] 中 else: - j = m - 1 # 此情况说明首个小于 target 的元素在区间 [i, m-1] 中 + j = m - 1 # 首个小于 target 的元素在区间 [i, m-1] 中 if i == len(nums) or nums[i] != target: return -1 # 未找到目标元素,返回 -1 return i diff --git a/chapter_searching/replace_linear_by_hashing.md b/chapter_searching/replace_linear_by_hashing.md index f4cda0a21..14c649455 100755 --- a/chapter_searching/replace_linear_by_hashing.md +++ b/chapter_searching/replace_linear_by_hashing.md @@ -6,9 +6,9 @@ comments: true 在算法题中,**我们常通过将线性查找替换为哈希查找来降低算法的时间复杂度**。我们借助一个算法题来加深理解。 -!!! question "两数之和" +!!! question - 给定一个整数数组 `nums` 和一个整数目标值 `target` ,请在数组中搜索“和”为目标值 `target` 的两个整数,并返回他们在数组中的索引。注意,数组中同一个元素在答案里不能重复出现。返回任意一个解即可。 + 给定一个整数数组 `nums` 和一个目标元素 `target` ,请在数组中搜索“和”为 `target` 的两个元素,并返回它们的数组索引。返回任意一个解即可。 ## 10.3.1.   线性查找:以时间换空间