http://www.cnblogs.com/darklights/p/5285598.html
谢谢这位前辈,让我理解得很清楚了。
''' 题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列。 例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。 思路: 先列举出根据当前输入字符串输出的所有可能的字符串, 将所有可能的字符串存储到一个列表中,再对列表排序后输出 python中的字符串是如何比较大小的:将字符串的每个字符转换成其所对应的ASCII码 由于字符串是可迭代的对象,则分别比较从两个字符串中迭代出来的字符的ASCII码 ASCII码值相等则继续比较下一位字符的ASCII码,直到完成终止 方法一:字典序的全排列算法 这道题目考察的是字典序的全排列算法: 列举出当前字符串中所有字符可能的全排列,并按照字典序输出 算法思路如下: # 显然: # 字典序最小的字符串是完全按照升序排列的字符串(相当于给最大的数值分配最小的权重) # 字典序最大的字符串则是按照降序排列的字符串 那么问题就转变成了,已知当前的字符串,如何求出下一个字典序上比它大的字符串呢? 这就需要用到字典序的全排列算法 假设当前的字符串是:124653 (1)从右边向左边遍历,找到第一个降序排列的字符串对(就是说,对于当前的字符,它比它右边邻域的字符小) 假设位置记作j(按照从左向右的索引),比如这里:j=2 对应的x[j]=4 由于存在这样降序排列的字符,故而之后可以在它的基础上增大 如果找不到任意一组相邻的字符串对,左边的字符大于右边的字符,则说明现在的字符串完全是降序排列,则全排列完成 (2)将字符串x划分成为 x1 x2……xj xj+1 …… xn 则由于xj和xj+1是从右向左遇到的第一组升序排列的字符串对 这意味着:从xj+1到xn的字符都是降序排列的(从大到小排列) 由于xj比xj+1小,则为了找到比当前的x稍微大一点的字符串,故而需要从xj+1到xn之间找到一个比xj大的最小的数 实际上也就是从右边向左边开始查找,查找到的第一个比xj大的数就是那个最小的数,记作xk (3)交换xj和xk的位置,这样在第j个位置上就找到了比当前字符串大一点的字符串 现在字符串变成了 x1 x2……xj-1 xk xj+1 …… xk-1 xj xk+1 …… xn 其中xk是从xj+1到xn之间(本来是降序排列的字符串)第一个比xj大的数 则从xj+1到xj之间的数值肯定都比xj大,然后从xk+1到xn的数肯定都比xj小, 这说明交换后,从xj+1到xn之间的字符串是降序排列的, 而由于已经交换了xj和xk,故而新得到的字符串肯定会变大,而希望又能最接近当前的字符串 所以希望从xj+1到xn之间的字符串能够是它们之间字符串的所有排列中最小的,也就是希望它们是升序排列的 而现在它们是降序排列的,故而只需要将它们逆序即可 ''' # -*- coding:utf-8 -*- class Solution: def Permutation(self, ss): # write code here if len(ss) == 0: return [] elif len(ss) == 1: return [ss] else: output=[] temp=sorted(ss) # print(temp) while(1): output.append(''.join(temp))#Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。 j=-100 for index in range(len(temp)-2,-1,-1): if temp[index]<temp[index+1]: j=index break if j==-100:#说明当前的temp字符串完全是降序排列的,则说明全排列结束 break else: k=-100 for index_2 in range(len(temp)-1,j,-1): if temp[index_2]>temp[j]: k=index_2 break mid=temp[j] temp[j]=temp[k] temp[k]=mid # 交换xj和xk的值 temp=temp[0:j+1]+temp[(j+1):][::-1] return output if __name__=='__main__': print(Solution().Permutation('aa'))