剑指offer python字符串的排列

85 篇文章 0 订阅

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'))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值