字符串的排列
输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。Last updated
输入一个长度为 n 字符串,打印出该字符串中字符的所有排列,你可以以任意顺序返回这个字符串数组。
例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。Last updated
class Solution:
def Permutation(self , s: str) -> List[str]:
N = len(s)
s = sorted(list(s))
used = [0] * N
ret = []
def dfs(d, tmp):
if d == N:
ret.append(''.join(tmp[:]))
return
for i in range(N):
# 基于树枝的剪枝
# if i > 0 and s[i] == s[i - 1] and used[i - 1]:
# continue
# 基于树层的剪枝(效率更高)
if i > 0 and s[i] == s[i - 1] and not used[i - 1]:
continue
if not used[i]:
used[i] = 1
tmp.append(s[i])
dfs(d + 1, tmp)
tmp.pop()
used[i] = 0
dfs(0, [])
return retclass Solution:
def Permutation(self, s: str) -> List[str]:
n = len(s)
s = list(s)
ret = []
def dfs(d):
if d == n:
ret.append(''.join(s))
return
book = set() # 记录用过的字符(剪枝)
for i in range(d, n): # 遍历 s[d] 及之后的字符
if s[i] not in book:
book.add(s[i])
s[d], s[i] = s[i], s[d] # 交换
dfs(d + 1)
s[d], s[i] = s[i], s[d] # 回溯
# book.remove(s[i]) # err,不需要清除标记
dfs(0)
return retclass Solution:
def Permutation(self, s: str) -> List[str]:
def next_permutation(a: List[str]) -> bool:
N = len(a)
# 从后向前查找第一个相邻顺序对 (i, i+1),即满足 a[i] < a[i+1];
# 此时 `a[i+1:n)` 必为递减序列
i = N - 2
while i >= 0 and a[i] >= a[i + 1]:
i -= 1
if i < 0: # i < 0,表示 a[0:n) 都是递减,即为最大排列
return False
else:
# 在 a[i+1:n) 中从后往前查找第一个 j 满足 a[i] < a[j]
j = N - 1
while j >= 0 and a[i] >= a[j]:
j -= 1
# 至此,找到了 靠左的“较小数” 和 靠右的“较大数”,交换
a[i], a[j] = a[j], a[i]
# 将 a[i+1:n) 反转,此时 a[i+1:n) 必为递减序列;
l, r = i + 1, N - 1
while l < r:
a[l], a[r] = a[r], a[l]
l += 1
r -= 1
return True
buf = sorted(s)
ret = [''.join(buf)]
while next_permutation(buf):
ret.append(''.join(buf))
return ret