6月22号,全排列问题详解

python里面的 全排列问题,实质上有一个简单的库函数可以调用:

itertools 是python 的内置函数

from itertools import combination

product:无序可重复
permutations:无序无重复
combinations:有序无重复
combinations_with_replacement:有序有重复

另外的解决方法,最常用的方法是回溯解法。同样也有递归的做法,递归的做法也有剪枝和不剪枝两种。非递归的方法是利用字典序找到下一个排列

关于回溯和递归的区别:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/79682147

https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/python-permutations-by-qubenhao-3yqy/

剑指 Offer 38. 字符串的排列

调用 permutations

class Solution:
    def permutation(self, s: str) -> List[str]:
        res=set()
        for i in itertools.permutations(s):
            res.add(''.join(i))
        return list(res)



简单回溯

class Solution:
    def permutation(self, s: str) -> List[str]:
        res=set()
        def dfs(s,ans):
            if not s:
                res.add(ans)
                return
            for i,c in enumerate(s):
                dfs(s[:i]+s[i+1:],ans+c)
        dfs(s,'')
        return list(res)



减枝回溯1

class Solution:
    def permutation(self, s: str) -> List[str]:
        res=[]
        s = sorted(list(s))
        def dfs(s,ans):
            if not s:
                res.append(ans)
                return
            for i,c in enumerate(s):
                if i==0 or c != s[i-1]:
                    dfs(s[:i]+s[i+1:],ans+c)
        dfs(s,'')
        return res



减枝回溯2

class Solution:
    def permutation(self, s: str) -> List[str]:
        if len(s)==1:
            return [s]
        res=[]
        for i,cha in enumerate(s):
            if cha not in s[:i]:
                for chas in self.permutation(s[:i]+s[i+1:]):
                    res.append(cha+chas)
        return res
        dfs(s,'')
        return list(res)



另一个方法是通过字典序,来找到对应的排列,所谓字典序就是在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序。

这里就要提到另一道题目

31. 下一个排列

cclass Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        #从后到前找到升序组合(i,j)
        #从j,end 找到最远的 nums[k]>nums[i]
        #swap
        #可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
        n,i = len(nums),-1
        for j in range(n-1,0,-1):
            if nums[j] > nums[j-1]:
                i = j-1
                break
        if i==-1:
            nums.sort()
            return nums
        for k in range(n-1,i,-1):
            if nums[k]>nums[i]:
                nums[k],nums[i] = nums[i],nums[k]
                break
        a=nums[i+1:]
        a.reverse()
        nums[i+1:]=a
        return nums



这是全排列的字典序解

class Solution:
    def permutation(self, s: str) -> List[str]:
            def nextPermutation(nums):
                """
                Do not return anything, modify nums in-place instead.
                """
                #从后到前找到升序组合(i,j)
                #从j,end 找到最远的 nums[k]>nums[i]
                #swap
                #可以断定这时 [j,end) 必然是降序,逆置 [j,end),使其升序
                n,i = len(nums),-1
                for j in range(n-1,0,-1):
                    if nums[j] > nums[j-1]:
                        i = j-1
                        break
                if i==-1:
                    nums.sort()
                    return nums
                for k in range(n-1,i,-1):
                    if nums[k]>nums[i]:
                        nums[k],nums[i] = nums[i],nums[k]
                        break
                a=nums[i+1:]
                a.reverse()
                nums[i+1:]=a
                return nums
            res=[]
            org,a = list(s),nextPermutation(list(s))
            while a != org:
                res.append(''.join(a)) 
                nextPermutation(a)
            res.append(''.join(a)) 
            return res

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值