概念
遍历树或图的方法,常用于子集,排列,组合等问题的求解。沿某一节点,尽可能深的搜索,当遇到边界条件或节点不满足条件时,回溯到上一节点。
模板
function dfs(cur){
if(边界条件){
相应操作
return;
}
for(遍历所有可能的选择){
是否满足题目条件
dfs(cur + 1);
回溯
}
}
二、例题
Leetcode 78 子集
返回数组的幂集合
//dfs1
var subsets = function(nums) {
const res = [];
const temp = [];
function dfs(nums, node, res) {
//构建边界条件
if(node == nums.length){
res.push([...temp]);
return;
}
//push,pop,对应选择与不选择当前节点加入子集构造
temp.push(nums[node]);
//选择该节点并向下搜索
dfs(nums,node + 1, res);
temp.pop(nums[node]);
//不选择该节点向下搜索
dfs(nums,node + 1, res);
}
dfs(nums,0,res);
return res;
};
//dfs2
var subsets = function(nums) {
const res = [];
const temp = [];
let backtrack = (cur) => {
res.push([...temp]);
//遍历每一种可能&&限制节点边界条件
for(let i = cur; i < nums.length; i++){
//构建子集
temp.push(nums[i]);
//沿该节点向下搜索填充子集
backtrack(i + 1);
//不含该节点向下搜索填充子集
temp.pop();
}
}
backtrack(0);
return res;
};
//位运算,二进制编号
//0,1分别代表选择与不选择该数字加入子集
var subsets = function(nums) {
let len = nums.length;
let res = [];
//遍历 0——2**n-1 的所有编号
//例 000 - 111
for(let i = 0; i < (1 << len); ++i){
//构建子集
let temp = [];
//查看0-n位是否为1
for(let j = 0; j < len; ++j){
if(i & (1 << j)){
temp.push(nums[j]);
}
}
res.push(temp);
}
return res;
};