1. 程式人生 > >【LeetCode】47全排列II

【LeetCode】47全排列II

題目解析

本題也就是全排列的基礎上增加了一個去重。不過需要注意的是在刪除元素的時候一定要刪除最後一個,不要用remove,因為remove會優先刪除第一個找到的。具體去重的思想為回溯剪枝,也就是遇到前面已經搜尋過的就不再搜尋了。不過,簡單的去重後來發現會出超時,所以應該考慮更加深入的剪枝。

剪枝思路:對於每一層的結點,如果已經有上一個結點加入過搜尋樹,那這一層就不需要再新增該結點了。用一個臨時變數temp來儲存已經有過搜尋的結點,如果當前結點等於temp,就說明前面已經搜尋過該結點,如果不等於,說明還沒有搜尋過,繼續搜尋。具體程式碼如下:

程式碼解答(py)


import copy
res = []
class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res.clear()
        if len(nums) == 0:
            return []
        if len(nums) == 1:
            return [nums]
        for i in range(len(nums)):
            self.permuteHelper([nums[i]], nums[0:i] + nums[i + 1:])
        return res

    def permuteHelper(self, before, nums):
        now = copy.deepcopy(before)
        if len(nums) == 1:
            now.append(nums[0])
            if now not in res:
                res.append(now)
        else:
            temp = -99991
            for i in range(len(nums)):
                if temp != nums[i]:
                    now.append(nums[i])
                    self.permuteHelper(now, nums[0:i] + nums[i + 1:])
                    now.pop()
                    temp = nums[i]
程式碼思路:res作為最後的結果集,nums先排序,進入Helper,遞迴返回條件是搜尋到最後一個數了,如果後面的數字還比較多,可以用temp來作為臨時變數,然後temp比較此時的搜尋,如果不等於說明該點還沒有被搜尋過,然後開始搜尋。最後在每一層都有剪枝。