题目链接
题目
输入一个字符串,打印出该字符串中字符的所有排列。例如,输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
示例:
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
限制:
- 1 <= s 的长度 <= 8
题解
回溯
复杂度分析
- 时间复杂度:O(n×n!),其中 n 为给定字符串的长度。这些字符的全部排列有 O(n!) 个,每个排列平均需要 O(n) 的时间来生成。
- 空间复杂度:O(n)。我们需要 O(n) 的栈空间进行回溯,注意返回值不计入空间复杂度。
/**
* @param {string} s
* @return {string[]}
*/
/**
* @param {string} s
* @return {string[]}
*/
var permutation = function(s) {
const res = [], vis = [];
const n = s.length;
const strArray = Array.from(s).sort(); // 排序方便下面字符去重
const perm = [];
const backtrack = (strArray, i) => {
if (i === n) {
res.push(perm.toString()); // 固定完所有字符,放入数组中
return;
}
for (let j = 0; j < n; j++) {
if (vis[j] || (j > 0 && !vis[j - 1] && strArray[j - 1] === strArray[j])) {
// 去重(已经走过的 或者 遇到两个相同字母的情况)
continue;
}
vis[j] = true; // 标记已经用过
perm.push(strArray[j]);
backtrack(strArray, i + 1); // 填下一个位置
perm.pop();
vis[j] = false;
}
}
backtrack(strArray, 0);
const size = res.length;
const recArr = new Array(size).fill(0);
for (let i = 0; i < size; i++) {
recArr[i] = res[i].split(',').join('');
}
return recArr;
};