理解全排列算法

先上一个代码和一个图
在这里插入图片描述

def permutations(arr,position,end):
    if position == end:
        print(arr)
    else:
        for index in range(position,end):
            arr[index],arr[position] = arr[position],arr[index]		#A
            permutations(arr,position+1,end)							#B
            arr[index],arr[position] = arr[position],arr[index]		#C
            
arr = ['a','b','c']
permutations(arr,0,len(arr))

全排列的思路是:

1.让字符串首字符(设为i)和每一个字符交换,包括它自己。得到子串集
2.对于子串集中每一个字符固定首字符,之后的字符串按照1处理,直到子串集的长度为1返回。

上个图

对应上面的思路,逻辑是这样的:
1.在0层用a交换所有的字符得到子串集abc bac和cba
2.他们三个都要处理,拿第一个举例,abc我们固定了a,然后对bc像1那样进行交换生成bc和cb
3.之后我们处理bc 固定b后剩下c可以返回了 这串就是abc, cb那条返回了acb。说到底就是上面思路中的1和2反复执行。

代码理解:
A处我们在循环中交换了第一个字符和所有的字符各一次,对应思路中的步骤1。
B处我们通过position+1固定了子串的第一个字符,这样就不处理这个字符了,因为range范围在(position,end)
C处这样理解:在for循环中我们为了完成步骤1中的交换,交换是用首字符和后面所有字符进行交换,每次交换后为了达到这个效果得把首字符还原回来,所以要进行完全相反的操作就有了C这一行,有点初始化的意思。
执行上:程序上它是先完成一个深度,也就是第一次它会固定a然后固定b然后固定c这样递归进去,第一个生成的字符串也就是abc。第二次生成的自然是从固定a开始bc的交换,固定c之后就是acb了,以此类推。


关于全排列的问题,这次遇到了一个。
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
解决这个问题我们首先建立了一个字典,然后代码如下:

n = len(digits)
res = []
def helper(i,tmp):
    if i == n:
        res.append(tmp)
        return 
    for alp in lookup[digits[i]]:
        helper(i+1,tmp+alp)
helper(0,"")

可以看到核心代码中helper函数处使用了递归来生成需要的排列,当计数器i和我们需要的长度一样的时候把tmp加入到res中并且返回,递归的时候是针对lookup【digits【i】】中的每一个项进行递归,就是i=0 时候a/b/c,i=1时候的d/e/f。在传入下一层递归的时候tmp传入的是上一层的tmp加上这一层的字符alp。所以第一次生成的顺序是 a – d —g然后g跳出来换成h/i,因为ghi是i=2 ghi的拆分遍历的结果。当i = 2 =n的时候res中加入了tmp(内容是adg)然后return,res中就保存了第一条生成的数据了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值