第七章 回溯算法part01
今日内容:
- 理论基础
- 77. 组合
-
class Solution { List<List<Integer>> result = new ArrayList<>(); LinkedList<Integer> path = new LinkedList<>(); public List<List<Integer>> combine(int n, int k) { combineHelper(n, k, 1); return result; } /** * 每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围,就是要靠startIndex * @param startIndex 用来记录本层递归的中,集合从哪里开始遍历(集合就是[1,...,n] )。 */ private void combineHelper(int n, int k, int startIndex){ //终止条件 if (path.size() == k){ result.add(new ArrayList<>(path)); return; } for (int i = startIndex; i <= n - (k - path.size()) + 1; i++){ path.add(i); combineHelper(n, k, i + 1); path.removeLast(); } } }
这段代码使用了深度优先搜索(DFS)的思想来解决组合问题。DFS 是一种通过递归的方式在搜索树中深入探索,并在到达叶子节点时回溯到上一层节点的算法。
对于这段代码来说,每层递归代表了生成组合的一个位置,从左到右依次选择可能的元素,并且在每一层中从当前位置的下一个数字开始搜索,直到达到组合的长度为止。
具体步骤如下:
- 初始化一个空的列表
result
用于保存所有可能的组合。 - 初始化一个空的链表
path
用于保存当前正在生成的组合。 -
这种方式通过深度优先搜索,逐步生成组合,并在需要时进行回溯,从而找到所有可能的组合。
- 调用
combineHelper
方法,并传入初始参数n
、k
和startIndex
。 - 在
combineHelper
方法中,首先判断path
的长度是否等于k
,如果是,则说明已经生成了一个满足条件的组合,将其添加到result
列表中,并返回。 - 如果
path
的长度不等于k
,则需要继续生成组合。 - 在当前层的循环中,从
startIndex
开始遍历可能的组合元素,直到n - (k - path.size()) + 1
,这是为了确保剩余的数字数量足够组成一个长度为k
的组合。 - 对于每个可能的组合元素,将其添加到
path
链表的末尾。 - 然后,递归调用
combineHelper
,并将startIndex
更新为当前数字的下一个数字,以在下一层继续生成组合。 - 当递归返回时,需要将
path
链表的最后一个元素移除,实现回溯操作,从而继续生成其他可能的组合。 - 最终,当所有的组合都生成完毕时,将
result
列表作为最终结果返回。