python里面的 全排列问题,实质上有一个简单的库函数可以调用:
itertools 是python 的内置函数
from itertools import combination
product:无序可重复
permutations:无序无重复
combinations:有序无重复
combinations_with_replacement:有序有重复
另外的解决方法,最常用的方法是回溯解法。同样也有递归的做法,递归的做法也有剪枝和不剪枝两种。非递归的方法是利用字典序找到下一个排列
关于回溯和递归的区别:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/79682147
调用 permutations
class Solution:
def permutation(self, s: str) -> List[str]:
res=set()
for i in itertools.permutations(s):
res.add(''.join(i))
return list(res)
简单回溯
class Solution:
def permutation(self, s: str) -> List[str]:
res=set()
def dfs(s,ans):
if not s:
res.add(ans)
return
for i,c in enumerate(s):
dfs(s[:i]+s[i+1:],ans+c)
dfs(s,'')
return list(res)
减枝回溯1
class Solution:
def permutation(self, s: str) -> List[str]:
res=[]
s = sorted(list(s))
def dfs(s,ans):
if not s:
res.append(ans)
return
for i,c in enumerate(s):
if i==0 or c != s[i-1]:
dfs(s[:i]+s[i+1:],ans+c)
dfs(s,'')
return res
减枝回溯2
class Solution:
def permutation(self, s: str) -> List[str]:
if len(s)==1:
return [s]
res=[]
for i,cha in enumerate(s):
if cha not in s[:i]:
for chas in self.permutation(s[:i]+s[i+1:]):
res.append(cha+chas)
return res
dfs(s,'')
return list(res)
另一个方法是通过字典序,来找到对应的排列,所谓字典序就是在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序。
这里就要提到另一道题目
cclass Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
#从后到前找到升序组合(i,j)
#从j,end 找到最远的 nums[k]>nums[i]
#swap
#可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
n,i = len(nums),-1
for j in range(n-1,0,-1):
if nums[j] > nums[j-1]:
i = j-1
break
if i==-1:
nums.sort()
return nums
for k in range(n-1,i,-1):
if nums[k]>nums[i]:
nums[k],nums[i] = nums[i],nums[k]
break
a=nums[i+1:]
a.reverse()
nums[i+1:]=a
return nums
这是全排列的字典序解
class Solution:
def permutation(self, s: str) -> List[str]:
def nextPermutation(nums):
"""
Do not return anything, modify nums in-place instead.
"""
#从后到前找到升序组合(i,j)
#从j,end 找到最远的 nums[k]>nums[i]
#swap
#可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
n,i = len(nums),-1
for j in range(n-1,0,-1):
if nums[j] > nums[j-1]:
i = j-1
break
if i==-1:
nums.sort()
return nums
for k in range(n-1,i,-1):
if nums[k]>nums[i]:
nums[k],nums[i] = nums[i],nums[k]
break
a=nums[i+1:]
a.reverse()
nums[i+1:]=a
return nums
res=[]
org,a = list(s),nextPermutation(list(s))
while a != org:
res.append(''.join(a))
nextPermutation(a)
res.append(''.join(a))
return res