回溯
回溯法解决的问题都可以抽象为树形结构
集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。
回溯部分的模板:1.选择(树层) 2.递归(树枝方向) 3.撤回选择
for循环用来横向遍历,递归的过程是纵向遍历。
回溯算法:列出所有可能性
Leecode
77.组合
回溯+剪枝,这个讲的很清楚
回溯:向下的树枝部分从当前节点的下一个结点开始
剪枝:
例子,n = 4,k = 4的话,那么第一层for循环的时候,从元素2开始的遍历都没有意义了。 在第二层for循环,从元素3开始的遍历都没有意义了。
所以就是还需要的个数 = k(需要的个数) - path.size()(path中已有的个数),
i
<
=
n
−
(
k
−
p
a
t
h
.
s
i
z
e
(
)
)
+
1
i<=n-(k-path.size())+1
i<=n−(k−path.size())+1
例如:第一层,需要 4个=4-0,i最高只能取到1
第二层:需要3个=4-1,i 最高只能取到 2
class Solution {
List<List<Integer>> res = new ArrayList<>();
Deque<Integer> path = new ArrayDeque<>();
public List<List<Integer>> combine(int n, int k) {
backtracking(n,k,1);
return res;
}
private void backtracking(int n,int k, int s){
if(path.size() == k){
res.add(new ArrayList(path));
return;
}
for(int i=s;i<=n-(k-path.size())+1;i++){ //开始剪枝
path.push(i);
backtracking(n,k,i+1);
path.pop();
}
}
}