剑指offer——字符串的排列

 

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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']

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值