1. 程式人生 > >Leetcode 90:子集 II(最詳細的解法!!!)

Leetcode 90:子集 II(最詳細的解法!!!)

給定一個可能包含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

示例:

輸入: [1,2,2]
輸出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

解題思路

這個問題是之前問題Leetcode 78:子集(最詳細的解法!!!)的擴充套件。我們用之前的解法會出現這樣的問題,[1,2]會出現兩次,因為我們有兩個2。最簡單的思路就是新增一個判斷if tmp not in result,並且我們要對nums排序,為什麼?為了避免出現這種情況

1,4,1
4,1,1

這兩種在這個問題中是一種情況,但是在判斷[1,4,1]==[4,1,1]

,兩者是不相同的。

class Solution:
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if not nums:
            return [[]]

        nums.sort()
        result = self.subsetsWithDup(nums[1:])
        return result + [[nums[0
]] + s for s in result if [nums[0]] + s not in result]

可想而知,這種做法顯然不是最快的。實際上我們這裡可以參考 Leetcode 40:組合總和 II(最詳細的解法!!!)的回溯法寫法,再迴圈中新增一步判斷即可。

class Solution:
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        result = list()
        self._subsetsWithDup(nums, 0
, list(), result) return result def _subsetsWithDup(self, nums, index, path, result): result.append(path.copy()) for i in range(index, len(nums)): if index < i and nums[i] == nums[i - 1]:# add continue self._subsetsWithDup(nums, i + 1, path + [nums[i]], result)

同樣的,對於遞迴可以解決的問題,我們都應該思考是不是可以通過迭代解決。

class Solution:
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        result = [[]]
        for i, _ in enumerate(nums):
            if i == 0 or nums[i] != nums[i - 1]:
                start = len(result)

            end = len(result)
            for j in range(end - start, end):
                result += [result[j] + [nums[i]]]
        return result

如有問題,希望大家指出!!!