面试题 08.08. 有重复字符串的排列组合
题目描述
有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。
示例1:
输入:S = "qqe" 输出:["eqq","qeq","qqe"]
示例2:
输入:S = "ab" 输出:["ab", "ba"]
提示:
- 字符都是英文字母。
- 字符串长度在[1, 9]之间。
解法
方法一:排序 + 回溯
我们可以先对字符串按照字符进行排序,这样就可以将重复的字符放在一起,方便我们进行去重。
然后,我们设计一个函数 \(\textit{dfs}(i)\),表示当前需要填写第 \(i\) 个位置的字符。函数的具体实现如下:
- 如果 \(i = n\),说明我们已经填写完毕,将当前排列加入答案数组中,然后返回。
- 否则,我们枚举第 \(i\) 个位置的字符 \(\textit{s}[j]\),其中 \(j\) 的范围是 \([0, n - 1]\)。我们需要保证 \(\textit{s}[j]\) 没有被使用过,并且与前面枚举的字符不同,这样才能保证当前排列不重复。如果满足条件,我们就可以填写 \(\textit{s}[j]\),并继续递归地填写下一个位置,即调用 \(\textit{dfs}(i + 1)\)。在递归调用结束后,我们需要将 \(\textit{s}[j]\) 标记为未使用,以便于进行后面的枚举。
在主函数中,我们首先对字符串进行排序,然后调用 \(\textit{dfs}(0)\),即从第 \(0\) 个位置开始填写,最终返回答案数组即可。
时间复杂度 \(O(n \times n!)\),空间复杂度 \(O(n)\)。其中 \(n\) 是字符串 \(s\) 的长度。需要进行 \(n!\) 次枚举,每次枚举需要 \(O(n)\) 的时间来判断是否重复。另外,我们需要一个标记数组来标记每个位置是否被使用过,因此空间复杂度为 \(O(n)\)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|