最近在刷剑指offer的题,刚好这题与网易的一道笔试题颇有渊源,特此记录一下解法。
解法一:最常见的解法莫属固定交换法了(个人理解),固定即先固定一个字母不变,通常固定在子串的首位,如abc固定a,对bc再进行全排列,bc串中固定b,对c进行全排列。交换即在a固定的情况下已经对bc子串进行了全排列之后,那么就将a与第二位的b交换变成bac,此时再回到了固定的步骤,只需固定b,对字串ac进行全排列。依此类推,直至交换完。
特别的需要注意,有重复元素的情况,如aab,那么只需加一个判定条件,当交换的元素相同就无需进行交换,直接跳过即可。千言万语不如上代码。嘿嘿!
class Solution:
def Permutation(self, ss):
# write code here
if not ss or not len(ss):
return ss
self.res = []
self.permution(list(ss), 0, len(ss))
return sorted(self.res)
def permution(self, ss, index, length):
if length-1 == index:
self.res.append(''.join(ss))
return
for i in range(index, length):
if (ss[i] == ss[index] and i != index):
continue
a = ss[i]
ss[i] = ss[index]
ss[index] = a
self.permution(ss, index+1, length)
#前面交换后,此处必须换回来,再进行下一次的固定交换法则
#要不会有重复的情况(当然你也可以用set或者判断not in 来避免重复)
a = ss[i]
ss[i] = ss[index]
ss[index] = a
return
解法二:以前看的一位大佬写的代码,颇有韵味。(ps:找不到原链接了,只能冒昧直接贴上代码了。)我简单总结为留一排他法,留一即将一位留出来,排他即将剩下的进行全排列,然后将留出来的分别拼到全排列串的首位。如abc,留a,排bc得bc、cb,拼:a+bc,a+cb,结果,abc,acb。再留b,排ac。。。。。。。依此类推。接着上代码。
class Solution:
def Permutation(self, ss):
if len(ss)==0:
return []
if len(ss)==1:
return[ss]
res=set()
for i in range(len(ss)):
for j in self.Permutation(ss[:i]+ss[i+1:]):
res.add(ss[i]+j)
return sorted(res)
简短精悍,惊为天人。