题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
输出描述:
输出一个包含字符串的列表。若输入为空串,则返回空列表`[]`
解题思路:
考察字符串“abc”, 可以这样递归地产生排列串:
第一个字母为“a”:
再考虑子串“bc”,重复步骤
第一个字母为“b”:
...
第一个字母为“c”:
...
第一个字母为“b”:
再考虑子串“ac”,重复步骤
第一个字母为“a”:
...
第一个字母为“c”:
...
第一个字母为“c”:
再考虑子串“ab”,重复步骤
第一个字母为“a”:
...
第一个字母为“b”:
...
这个递归程序将分为#ss层,显然,在第l个层,实际上只是将第i个字符搬到第l个位置来,并将原来的第l,l+1,...,i-1个位置处的字符后移一位。如果第i个字符跟第l个字符相同,那么这种搬移操作就可以免了。
所以,代码如下:
class Solution:
def __init__(self):
self.res = []
###################################################
# Core algorithm: shift #i to #l
# [ ]...[ ][ ]< >[ ][ ]...[ ]
# ^ |
# | |
# -------------
###################################################
def shift(self, chrs, l, i, n):
chrs1 = ['']*n
for j in range(n):
if j == l:
chrs1[l] = chrs[i]
elif l < j <= i:
chrs1[j] = chrs[j-1]
else:
chrs1[j] = chrs[j]
return chrs1
def handle(self, chrs, l, n):
if l < n - 1:
for i in range(l, n):
if not(l < i and chrs[l] == chrs[i]): # handle duplicate chars
self.handle(self.shift(chrs, l, i, n), l+1, n)
else:
self.res.append(''.join(chrs))
return
def Permutation(self, ss):
n = len(ss)
if n > 0:
chrs = [c for c in ss]
self.handle(chrs, 0, n)
return self.res
测试代码:
if __name__ == "__main__" :
print(Solution().Permutation(''))
print(Solution().Permutation('abc'))
print(Solution().Permutation('aba'))
测试结果:
[]
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
['aba', 'aab', 'baa']