leetcode.78\90\491回溯算法—子集问题

子集问题就是收集所有节点,即收割的时候不需判断,直接收割

lc78——子集

这个题的题目已经说了nums元素互不相同,无需自己去重

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        def backtracking(startindex):
            res.append(path[:])
            if startindex == len(nums):
                return

            for i in range(startindex, len(nums)):
                path.append(nums[i])
                backtracking(i+1)
                path.pop()
        backtracking(0)
        return res

lc90——子集II

这个题需要自己去重,先排列,然后对每层的for循环来去重就行

#再讲一下个人对本层for循环去重的理解
                #首先对于本层for循环出现的第一个数,一定是需要的(因此 i>startindex )
                #nums[i-1]的待选集合一定包含nums[i]的待选集合
                #因此当nums[i-1]入选后,若nums[i]与之相同则一定会重复子集,去掉

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res = []
        path = []
        def backtracking(startindex):
            res.append(path[:])
            
            for i in range(startindex, len(nums)):
                #再讲一下个人对本层for循环去重的理解
                #首先对于本层for循环出现的第一个数,一定是需要的(因此 i>startindex )
                #nums[i-1]的待选集合一定包含nums[i]的待选集合
                #因此当nums[i-1]入选后,若nums[i]与之相同则一定会重复子集,去掉
                if i > startindex and nums[i] == nums[i-1]:
                    continue
                path.append(nums[i])
                backtracking(i+1)
                path.pop()
        backtracking(0)
        return res

lc491——非递减子序列

本题不能再对nums排序,去重需要重新考虑

还是对本层for循环去重,用一个set(或者是其他什么列表之类的)来存储访问过的值,后续for循环中如果再次访问到,就跳过

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res = []
        path = []
        
        def backtracking(startindex):
            if len(path) >= 2:
                res.append(path[:])

            visited_set = set()
            for i in range(startindex, len(nums)):
                if (path and nums[i] < path[-1]) or nums[i] in visited_set:
                    continue
                else:
                    visited_set.add(nums[i])
                    path.append(nums[i])
                    backtracking(i+1)
                    path.pop()
        backtracking(0)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值