void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
思路:使用回溯法进行多层遍历实现解题,可使用剪枝加快不可满结果继续计算时,就提前结束当前的分支的递归过程。
// 时间复杂度O((n+1)n/2) = O(n^2)
// 空间复杂度O(n^2)
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> list = new ArrayList<>();
boolean[] visited = new boolean[n];
backtracking(0, n, k, -1, list, ans);
return ans;
}
// 参数说明
// count用来计数list中元素的个数;
// n,k不解释;
// index用来剪枝颠倒组合的情况发生,保证只有一个方向的组合
// list存储每一次形成的可行组合,ans全局结果集
public void backtracking(int count, int n, int k, int index, List<Integer> list, List<List<Integer>> ans){
// 停止条件
if(count == k){
ans.add(new ArrayList<Integer>(list)); // 收集结果
return;
}
// 剪枝,用的用的是k-count还需要几个数,与n-index-1还剩几个可选进行的比较用来剪枝
if(k-count > n-index-1)
return;
// 递归处理
for(int i = index+1; i<n; i++){
count++;
list.add(i+1);
backtracking(count, n, k, i, list, ans);
// 回溯
count--;
list.remove(list.size()-1);
}
return;
}}