📅  最后修改于: 2023-12-03 15:39:02.807000             🧑  作者: Mango
给定一个字符串,编写一个函数来计算该字符串的所有排列。要求在排列中,任意相邻的字符不能相同。
例如,给定字符串 "abb"
,返回排列 ["abc", "acb", "bac", "bca", "cab", "cba"]
。
该问题可以通过回溯法解决。具体而言,对于每个字符位置,我们枚举所有的可填字符(即还没有填过的字符),并递归搜索下去。同时,我们需要对每个字符位置进行剪枝操作,保证填入字符后不会出现相邻的字符相同的情况。
具体实现时,我们可以建立一个标记数组 visited
来标记每个位置是否被填过,然后进行回溯搜索。在回溯搜索的过程中,我们维护一个当前排列 perm
,表示已经填出的字符以及它们的相对顺序,下一个枚举到的字符应填在哪个位置。
class Solution:
def permutation(self, s: str) -> List[str]:
n = len(s)
perm = []
visited = [False] * n
res = []
def backtrack():
if len(perm) == n:
res.append("".join(perm))
return
for i in range(n):
if visited[i] or (i > 0 and s[i] == s[i - 1] and not visited[i - 1]):
continue
perm.append(s[i])
visited[i] = True
backtrack()
visited[i] = False
perm.pop()
s = sorted(s)
backtrack()
return res
回溯算法的时间复杂度较高,本题时间复杂度为 $O(n \times n!)$,其中 $n$ 是字符串的长度。
空间复杂度为 $O(n)$,即为回溯时维护的标记数组 visited
的空间复杂度。