47. Permutations II

https://leetcode.com/problems/permutations-ii/description/
给定一个可包含重复数字的序列,返回所有不重复的全排列。

思路:回溯。因为有重复数字,所以不能简单用in运算符去重,改用一个不耳数组used,used[i]=True表示该位置已经用过。
回溯之前还应该排序,便于排除重复结果。
此外还需设置一个特殊条件来排除重复结果:used[i] or i-1 >= 0 and nums[i-1] == nums[i] and not used[i-1]
used[i]表示i如果使用了,跳过,很好理解
i-1 >= 0 and nums[i-1] == nums[i] and not used[i-1]表示看前一位,若与当前相等,且前一位未使用过,则跳过。例如对nums=[1,1,1,2],三个1是重复元素,取的时候应该作为一个整体取,即nums的0,1,2号,否则会出现重复结果。上面条件的限制使得nums[1]只有在nums[0]出现的时候才取,同理nums[2]只有在nums[1]出现的时候才取,因此保证了结果中三个1的取用先后次序为nums的0,1,2号。
注意,not used[i-1]也可以改成used[i-1],即前一位使用过,则跳过。还是上面的例子,nums[0]出现后,nums[1]取不了,nums[1]出现后,nums[2]取不了,因此三个1的情况只有是先取nums的2号,然后是1号和0号,和上面反过来

两种思路都可行,都是为了保证相同元素的有序性,从而避免重复

class Solution:
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        tmpList = []
        used = [False] * len(nums)
        nums.sort()  #重要,先排序
        self.backtrack(nums, res, tmpList, used)
        return res

    def backtrack(self, nums, res, tmpList, used):
        if len(tmpList) == len(nums):
            res.append(list(tmpList))
        else:
            for i in range(len(nums)):
                if used[i] or i-1 >= 0 and nums[i-1] == nums[i] and not used[i-1]:  #注意复杂条件,最后一个可改为used[i-1]
                    continue
                used[i] = True
                tmpList.append(nums[i])
                self.backtrack(nums, res, tmpList, used)
                used[i] = False  #记得“还原现场”
                tmpList.pop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值