[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eZ9fWOEw-1645014280964)(C:\Users\winches\Desktop\全排序.png)]
let permute = (num)=>{
res = []
// path用来保存每次选的路径
dfs([])
function dfs(path){
// 判断是否选择完全
if(path.length === num.length){
// 将数组转为字符串并加到结果数组中
path = path.join('') // 若是数组需要返回 path = [...path]
res.push(path)
return
}
for(let i = 0 ;i<num.length;i++){
// 判断路径里有没有重复
if(path.includes(num[i])){
continue
}
// 将无重复的放入路径中
path.push(num[i])
// 递归深入选择
dfs(path) // 到选择完path长度等于num长度后递归结束开始回溯
// 最后选择完后将选择完的路径弹出并回溯到一个循环开始下一次选择
path.pop()
}
}
// 最后递归完返回结果
return res
}
结合上图及代码一步一步写下步骤就能理解深度优先选择及递归函数就能解决全排问题
改版后能适应( aab ) 重复类型
var permutation = function(s) {
// 创建一个数组用来保存状态
let used = Array(s.length).fill(false)
// 将结果放进集合用来去重
let res = new Set()
dfs([],used)
function dfs(path,used){
// 递归结束条件
if(path.length == s.length){
// 将path拼串'a','b','c' --> 'abc' 随后放入结果数组
res.add(path.join(''))
return
}
for(let i = 0; i < s.length; i++){
// 若该字母已放进路径则跳过
if(used[i]) continue
// 将已放入路径的标记
used[i] = true
path.push(s[i])
// 递归每一层的字符串
dfs(path,used)
// 将递归完的字符串出栈到上一层,状态还原,并进行下一次递归
path.pop()
used[i] = false
}
}
// 将结果转为数组
return [...res]
};
console.log(permutation('aab'));
用字符串保存路径
var permutation = function (s) {
let res = new Set;
let used = Array(s.length).fill(false);
let dfs = (str, used) => {
if (str.length == s.length) {
res.add(str);
return;
}
for(let i = 0; i < s.length; i++){
if(used[i]) continue;
else {
used[i] = true;
dfs(str+s[i], used);
used[i] = false;
}
}
}
dfs('', used);
return [...res];
};