leetcode-DFS

转载自:https://www.bilibili.com/video/BV1qE411E7di?from=search&seid=13624967053223072523

dfs三个重要的点:

  1. 截止条件
  2. 遍历候选节点
  3. 对候选节点的筛选

例题一:
输入: p = ‘A’,‘B’,‘C’
输出:ABC ACB BAC BCA CAB CBA

  1. 截止条件:level==p.length()+1
  2. 遍历候选节点:for(var i=0; i<p.length; i++)
  3. 筛选候选节点:pb=【false,false,false】,代表该节点还未被使用,使用时push入res,将pb[i]置为true
  4. 另外,每一层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);
            }
        }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值