这个是带重复的,需要剪枝
看图思路非常清晰:如果前面那个数和我一样但是没用过,这说明我们在同一层,说明此时我在for循环中,直接continue。如果不在同一层,而是竖向的不可能出现我前面和我一样但是它没用过,只有它探索完了,把它吐出来,for循环往后推一位才会出现这种现象。
var permuteUnique = function (nums) {
nums.sort((a, b) => {
return a - b;
})
let res = new Array();
let uesd = new Array();
for (let i = 0; i < nums.length; i++) {
uesd[i] = false;
}
function dfs(path, uesd) {
if (path.length >= nums.length) {
if (path.length == nums.length)
res.push([...path]);
return;
}
for (let i = 0; i < nums.length; i++) {
if (uesd[i] == true) continue; //用过了的,无论是横竖都不可能重复使用
if (i != 0 && nums[i] == nums[i - 1] && uesd[i - 1] == false) {
continue; //我们在同一层,舍弃
}
path.push(nums[i]);
let cp = [...uesd];
// 这里用一个替身传进去最方便,什么事都不用管,让他自己探索
cp[i] = true;
dfs(path, cp);
path.pop();
}
}
dfs([], uesd);
return res;
};
这个是无重复元素的,我用了个set来保证每个元素访问一遍,也可以同上的方法保证,set传进去的时候也是用的替身.
var permute = function (nums) {
let res = new Array();
let set = new Set();
function dfs(path, set) {
if (path.length == nums.length) {
res.push([...path]);
return
}
if (path.length > nums.length)
return;
for (let i = 0; i < nums.length; i++) {
if (!set.has(nums[i]))
path.push(nums[i]);
else
continue;
dfs(path, copy(set).add(nums[i]));
path.pop();
}
}
dfs([], set);
return res;
};
function copy(set) {
let newset = new Set();
set.forEach(i => {
newset.add(i);
})
return newset;
}