https://leetcode.cn/problems/combinations/
题目要求
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
回溯
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> list = new LinkedList<>();
public List<List<Integer>> combine(int n, int k) {
dfs(1, n, k);
return res;
}
public void dfs(int index, int n, int k) {
// 递归结束条件
if (list.size() == k) {
res.add(new ArrayList<>(list));
return;
}
// 循环 回溯
for (int i = index; i <= n - (k - list.size()) + 1; i++) {
list.add(i);
dfs(i + 1, n, k);
list.removeLast();
}
}
}
总结
- 定义全局变量,可以减少函数中传递的参数,提高可读性;
- 剪枝的地方就在递归中每一层的for循环所选择的起始位置。
- 如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。
for (int i = index; i <= n - (k - list.size()) + 1; i++) // i为本次搜索的起始位置
+1
因为包括起始位置,我们要是一个左闭的集合。