刷刷刷 Day 24 | 77. 组合
77. 组合
LeetCode题目要求
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例
输入:n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
解题思路
先理解组合,在本题中,取 [1,4] 范围内的两个数,结果 [2,4] 和 [4,2] 是没有区别的。
组合的根本是穷举,而解决组合问题就是回溯法来实现。
解决问题前,牢记回溯模板
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
上代码
class Solution {
private List<List<Integer>> res = null;
private Deque<Integer> path = null;
public List<List<Integer>> combine(int n, int k) {
res = new ArrayList<>();
path = new LinkedList<>();
backtracking(n, k, 1);
return res;
}
private void backtracking(int n, int k, int startIndex) {
// [1, n] 范围内 k 个数的组合,如 k = 2 ,那么 [1,2] 就是一个结果
// 终止条件
if (path.size() == k) {
// 存放结果;
res.add(new ArrayList<>(path));
return;
}
// 从 startIndex 位置开始,穷举组合, i <= n-(k-path()) + 1 进行了剪枝优化
for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) {
// 处理节点;
path.add(i);
// 递归
backtracking(n, k, i + 1);
// 回溯,撤销处理结果
path.removeLast();
}
}
}
重难点
重点理解回溯方法,记住回溯模板,及剪枝优化
附:学习资料链接