回溯就是一个递归的过程
递归就一定是有中止的
回溯一般都是被抽象为一个N叉树
如上图所示:
树的宽度就是给定的集合的大小,通常是用for循环遍历的
树的深度就是递归来处理的
一般来说,递归方法都是没有返回值的
void 递归方法名(参数){
if(终止条件){
收集结果;
return;
}
//单层搜索
for(集合元素){
处理节点;
递归函数;
回溯操作(撤销处理的情况);//为什么要回溯可以看下面解释
}
return;
}
为什么要回溯?
如果处理:{1,2,3,4} 第一次:1,2 只有回溯到1,的时候,才能把3加进来,得到:1,3 同样,只有1,3回溯一下,才能得到1,4
如果不回溯有什么后果?
如果不回溯,就会一直:1,2,3,4一直加下去
回溯之组合问题
例如:
力扣第77题,组合。
https://leetcode-cn.com/problems/combinations/
- 组合
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
从示例中可以看出,n=4就是代表的是:从1-4之间的数
{1,2,3,4}
k=2代表,从{1,2,3,4}中找出2个数组合的数
那么就得到了:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
1、如果找出k=2的,2个数的组合,我们可以写两个for循环,进行暴力,例如:
for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){
sout(i+""+j);
}
}
2、如果找出k=3呢,3个数的组合,我们可以写三个for循环,进行暴力,例如:
for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){
for(int k=j+1;k<size;k++){
sout(i+""+j+""+k);
}
}
}
如果k=100,k=1000呢?总不能写100个,1000个for循环吧。
那么就可以用回溯来解决这个问题。
回溯如何解决组合问题?