转载自:https://www.bilibili.com/video/BV1qE411E7di?from=search&seid=13624967053223072523
dfs三个重要的点:
- 截止条件
- 遍历候选节点
- 对候选节点的筛选
例题一:
输入: p = ‘A’,‘B’,‘C’
输出:ABC ACB BAC BCA CAB CBA
- 截止条件:level==p.length()+1
- 遍历候选节点:for(var i=0; i<p.length; i++)
- 筛选候选节点:pb=【false,false,false】,代表该节点还未被使用,使用时push入res,将pb[i]置为true
- 另外,每一层dfs结束后,要有一个pop,恢复数值的动作,以便于下一轮遍历正常进行。因为对于下一个候选节点,要看到一样的现场。
function dfs(p,pb,level,res){
//1.截止条件
if (level==p.length+1){
console.log(res.join(" "));
return;
}
//2.遍历候选节点
for(var i=0; i<p.length; i++){
var c = p[i];
//3.筛选节点
if (!pb[i]){
res.push(c);
pb[i]=true;
dfs(p,pb,level+1,res);
res.pop();
pb[i]=false;
}
}
}
可以改进一下,不要level这个参数,当res装满3个时,就可以截止了
function dfs(p,pb,res){
//1.截止条件
if (res.length==p.length){
console.log(res.join(" "));
return;
}
//2.遍历候选节点
for(var i=0; i<p.length; i++){
var c = p[i];
//3.筛选节点
if (!pb[i]){
res.push(c);
pb[i]=true;
dfs(p,pb,res);
res.pop();
pb[i]=false;
}
}
}
继续改进,删去pb,用过的元素,在数组中置为null,pop时恢复
function dfs(p,res){
//1.截止条件
if (res.length==p.length){
console.log(res.join(" "));
return;
}
//2.遍历候选节点
for(var i=0; i<p.length; i++){
var c = p[i];
//3.筛选节点
if (c){
res.push(c);
p[i]=null;
dfs(p,res);
res.pop();
pb[i]=c;
}
}
}
res设为全局变量,可以再删去一个参数
var res = [];
function dfs(p){
//1.截止条件
if (res.length==p.length){
console.log(res.join(" "));
return;
}
//2.遍历候选节点
for(var i=0; i<p.length; i++){
var c = p[i];
//3.筛选节点
if (c){
res.push(c);
p[i]=null;
dfs(p);
res.pop();
pb[i]=c;
}
}
}
例题二:leetcode-17-电话号码的字母组合
class Solution {
//定义二维数组,用大括号
char[][] phone = {
{},
{},
{'a','b','c'},{'d','e','f'},
{'g','h','i'},{'j','k','l'},
{'m','n','o'},{'p','q','r','s'},
{'t','u','v'},{'w','x','y','z'}
};
public List<String> letterCombinations(String str) {
List<String> res = new ArrayList<>();
if (str.length() == 0) return res;
dfs(str, 0, new StringBuilder(), res);
return res;
}
void dfs(String str,int index, StringBuilder sb, List<String> res){
//1.截止条件
if (index == str.length()){
res.add(sb.toString());
return;
}
//2.遍历候选节点(注意这里的候选节点是a,b,c,不是2,3)
for(char c : phone[str.charAt(index)-'0']){
sb.append(c);
dfs(str, index+1, sb, res);
//这里不可以写成Index-1,删除最后面一个元素,用sb.length()-1来标记位置
sb.deleteCharAt(sb.length()-1);
}
}
}