DFS+回溯专题 - leetcode47. Permutations II ★

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a786150017/article/details/82961812

47. Permutations

题目描述

有重复数字的全排列

例子

Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

解法
法1 - 类似于有重复数字的全排列,最后再处理重复的排列。但比较耗时,不是最优解法
法2 - 改进法1,注意不能判断把pos!=i and nums[pos] == nums[i]作为continue的判别标准,比如2,1,1-自己画图看一下

解法1-1
类似于有重复数字的全排列,此处采用递归解法

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.dfs(nums, 0, res)
        return list(map(list, set(res)))
    
    def dfs(self, nums, pos, res):
        if pos == len(nums):
            res.append(tuple(nums))
        for i in range(pos, len(nums)):
            nums[pos], nums[i] = nums[i], nums[pos]
            self.dfs(nums, pos+1, res)
            nums[pos], nums[i] = nums[i], nums[pos]

解法1-2
非递归,固定某数字,依次在可能位置插入下一个数字

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        lastPerms = [[]]
        for num in nums:
            perms = []
            for lastPerm in lastPerms:
                for i in range(len(lastPerm)+1):
                    perms.append(lastPerm[:i] + [num] + lastPerm[i:])
            lastPerms = perms
        return list(set(map(tuple, lastPerms)))

解法2-1
定义一个visited,判断是否重复

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.dfs(nums, 0, res)
        return res
    
    def dfs(self, nums, pos, res):
        if pos == len(nums):
            res.append(nums[:])
        
        visited = set()
        for i in range(pos, len(nums)):
            if nums[i] in visited:
                continue
            visited.add(nums[i])
            nums[pos], nums[i] = nums[i], nums[pos]
            self.dfs(nums, pos+1, res)
            nums[pos], nums[i] = nums[i], nums[pos]

解法2-2
非递归改进,固定某数字,依次在可能位置插入下一个数字。但是不在和num重复的数字后插入num

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        lastPerms = [[]]
        for num in nums:
            perms = []
            for lastPerm in lastPerms:
                for i in range(len(lastPerm)+1):
                    perms.append(lastPerm[:i] + [num] + lastPerm[i:])
                    if i < len(lastPerm) and num == lastPerm[i]:
                        break
            lastPerms = perms
        return lastPerms

猜你喜欢

转载自blog.csdn.net/a786150017/article/details/82961812