@@ -3923,21 +3923,21 @@
2. 重复子集剪枝
我们考虑在搜索过程中通过剪枝进行去重。观察下图,重复子集是在以不同顺序选择数组元素时产生的,具体来看:
-- 第一轮和第二轮分别选择 \(3\) , \(4\) ,会生成包含这两个元素的所有子集,记为 \([3, 4, \cdots]\) 。
-- 若第一轮选择 \(4\) ,则第二轮应该跳过 \(3\) ,因为该选择产生的子集 \([4, 3, \cdots]\) 和
1. 中生成的子集完全重复。
+- 第一轮和第二轮分别选择 \(3\) , \(4\) ,会生成包含这两个元素的所有子集,记为 \([3, 4, \dots]\) 。
+- 若第一轮选择 \(4\) ,则第二轮应该跳过 \(3\) ,因为该选择产生的子集 \([4, 3, \dots]\) 和
1. 中生成的子集完全重复。
分支越靠右,需要排除的分支也越多,例如:
-- 前两轮选择 \(3\) , \(5\) ,生成子集 \([3, 5, \cdots]\) 。
-- 前两轮选择 \(4\) , \(5\) ,生成子集 \([4, 5, \cdots]\) 。
-- 若第一轮选择 \(5\) ,则第二轮应该跳过 \(3\) 和 \(4\) ,因为子集 \([5, 3, \cdots]\) 和子集 \([5, 4, \cdots]\) 和
1. , 2. 中生成的子集完全重复。
+- 前两轮选择 \(3\) , \(5\) ,生成子集 \([3, 5, \dots]\) 。
+- 前两轮选择 \(4\) , \(5\) ,生成子集 \([4, 5, \dots]\) 。
+- 若第一轮选择 \(5\) ,则第二轮应该跳过 \(3\) 和 \(4\) ,因为子集 \([5, 3, \dots]\) 和子集 \([5, 4, \dots]\) 和
1. , 2. 中生成的子集完全重复。

图:不同选择顺序导致的重复子集
-总结来看,给定输入数组 \([x_1, x_2, \cdots, x_n]\) ,设搜索过程中的选择序列为 \([x_{i_1}, x_{i_2}, \cdots , x_{i_m}]\) ,则该选择序列需要满足 \(i_1 \leq i_2 \leq \cdots \leq i_m\) ,不满足该条件的选择序列都会造成重复,应当剪枝。
+总结来看,给定输入数组 \([x_1, x_2, \dots, x_n]\) ,设搜索过程中的选择序列为 \([x_{i_1}, x_{i_2}, \dots , x_{i_m}]\) ,则该选择序列需要满足 \(i_1 \leq i_2 \leq \dots \leq i_m\) ,不满足该条件的选择序列都会造成重复,应当剪枝。
3. 代码实现
-为实现该剪枝,我们初始化变量 start ,用于指示遍历起点。当做出选择 \(x_{i}\) 后,设定下一轮从索引 \(i\) 开始遍历。这样做就可以让选择序列满足 \(i_1 \leq i_2 \leq \cdots \leq i_m\) ,从而保证子集唯一。
+为实现该剪枝,我们初始化变量 start ,用于指示遍历起点。当做出选择 \(x_{i}\) 后,设定下一轮从索引 \(i\) 开始遍历。这样做就可以让选择序列满足 \(i_1 \leq i_2 \leq \dots \leq i_m\) ,从而保证子集唯一。
除此之外,我们还对代码进行了两项优化:
- 在开启搜索前,先将数组
nums 排序。在遍历所有选择时,当子集和超过 target 时直接结束循环,因为后边的元素更大,其子集和都一定会超过 target 。
diff --git a/chapter_backtracking/summary/index.html b/chapter_backtracking/summary/index.html
index 9a3f29a1e..ae4f45ed4 100644
--- a/chapter_backtracking/summary/index.html
+++ b/chapter_backtracking/summary/index.html
@@ -545,7 +545,7 @@
- 第 2 章 复杂度
+ 第 2 章 时空复杂度
@@ -560,7 +560,7 @@