90. Subsets II

90. Subsets II

Description

Given an integer array nums that may contain duplicates, return all possible subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

Idea

这一题和subsets 一样但是唯一的区别是给的nums里有重复的数。所以在return的时候,可能会有同样的subset的情况。因为我们需要在选subset是就判断是否重复并及时舍弃重复的subset。
可以将nums先排序,然后在每次选则加入subset的元素时,如果当前原色和之前的元素值相同,则必须当之前的元素被选中的情况下才能选当前元素。换言之,在nums里,任意相同的元素,我们优先选取第一个或前几个元素。

Code

我们可以添加一个visited set,来判断在curr subset里,第 i - 1个元素有没有被选中。

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        if not nums or len(nums) == 0:
            return []
        res = []
        nums.sort()
        self.dfs(nums, 0, [], set(), res)
        return res
        
    def dfs(self, nums, index, curr, res):
        res.append(list(curr))
        for i in range(index, len(nums)):
        	# 当i和i-1元素相同时,如果i-1没有被选中,则我们跳过 i
            if i > 0 and nums[i] == nums[i - 1] and i - 1 not in visited:
                continue
            # 在每次加新的元素时,需要同时把该元素位置加到visited里
            curr.append(nums[i])
            visited.add(i)
            self.dfs(nums, i + 1, curr, visited, res)
            # 在遍历完包含此元素的subset后,也需要把该元素pop出,继续不包含此元素的其他subset
            curr.pop()
            visited.remove(i)

一个更简单的判断i-1是否被加到current subset的方法:
因为每次加了一个元素后,都会继续以该元素的下一个元素为起点去看剩下的元素。所以在每一层起始为index位置的搜索中,我们可以确定在当前subset curr中,最后一个元素一定是index - 1位置的元素。 而在当前层我们的工作是, 从 index 到 len(nums) - 1中选任何一个元素放到curr里,并从那个元素的位置开始继续向后寻找。所以当 i == index时,我们可以放心把 i 加到curr里,无论 i 是否与i - 1 相同。当 i > index时, 我们只需判断nums[i] nums[i-1]是否相等。 如果不相等,则我们可以跳过i-1选i。但如果想等我们则直接skip掉当前的i。因为所有需要i的subset,都会被包括在选到i的那个分支里,这里我们继续选就会造成重复。这个方法则不需要visited set,只需根据i和index的关系来判断i-1是否在curr里。

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        if not nums or len(nums) == 0:
            return []
        res = []
        nums.sort()
        self.dfs(nums, 0, [], res)
        return res
        
    def dfs(self, nums, index, curr, res):
        res.append(list(curr))
        for i in range(index, len(nums)):
        '''
            在这一层需要从index 到 len(nums) - 1里选一个加到curr
            index - 1是一定已经添加到curr里了,所以nums[index]可以直接放到curr里
            而任何nums[i - 1] = nums[i]的nums[i]都不能放到curr里
            因为非index的i都并没有被加到curr里,如果有两个数相同我们更应该先加i-1而不是i
        '''
            if i > index and nums[i] == nums[i - 1]:
                continue
            curr.append(nums[i])
            self.dfs(nums, i + 1, curr, res)
            curr.pop()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值