全排列-动态规划&回溯

题目出自力扣46.全排列47.全排列Ⅱ。前者给定一个不包含重复数字的序列nums,要求返回所有不重复的全排列;后者在此基础上加上了nums中可包含重复数字的条件。

示例1
输入:nums=[1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例2
输入:nums = [1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]

动态规划

假设已经得到含有n个元素的数组的全排列,现再加入一个未出现过的元素x,则x在当前任一排列中的任意位置插入,都能得到一个不同的排列序列。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        def insert(arr,num):
            res = []
            for i in range(len(arr)+1):
                temp = arr.copy()
                temp.insert(i,num)
                res.append(temp)
            return res

        ans = [[nums[0]]]
        i=1
        while i < len(nums):
            num = nums[i]
            subans = []
            for a in ans:
                subans+=insert(a,num)
            ans=subans
            i+=1
        return ans

但该方法不适合包含重复数字的情况:例如在nums=[1,2,1]时,由[1,2]可得到全排列[[1,2],[2,1]],再插入一个1时会得到[[1,1,2],[1,2,1],[1,2,1],[2,1,1]],出现重复元素[1,2,1]。

回溯

对于有length个元素的数组nums,考虑有length个空格将其填入。在第一个位置填入任一个数后,在剩下的数中选择一个填入下一个空位,直到只剩下最后一个位置未填,得到一个排列。
对于有重复元素的数组,只要将所有数字及其个数进行统计,相同的数字在一轮循环中只填入当前位置一次,就不会造成重复的现象。

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        def fill(first,arr,record):
            if first == length-1:
                ind = record.index(1)
                arr.append(ind-10)
                res.append(arr[:])
                arr.pop()
                return
            for i in range(21):
                if record[i]!=0:
                    arr.append(i-10)
                    record[i]-=1
                    fill(first+1,arr,record)
                    record[i]+=1
                    arr.pop()

        record = [0]*21 # 根据题意,nums的范围为[-10,10]
        for num in nums:
            record[num+10]+=1
        res=[]
        length = len(nums)
        fill(0,[],record)
        return res        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值