我是靠谱客的博主 鳗鱼万宝路,最近开发中收集的这篇文章主要介绍LeetCode每日一题(集合问题)78.子集,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

LeetCode每日练习78

  • 78.子集
    • 第一种方法,回溯递归
    • 思路二
    • 思路三
    • 相同的还有以下多种类似的问题

78.子集

题目概述

子集问题,看到这种题,肯定是可以用DFS加递归可以做的。首先分析思路,这种类似于全排列的情况,并且顺序不同算一种的话,其实就只要递归遍历就可以了

第一种方法,回溯递归

这题其实就是类似于全排列的问题,显而易见的是顺利不同的组合算是一个,例如[1,2,3], [1,3,2] , 因为数组中的元素是排序且无重复的,因此只需要考虑在递归进入下一阶段的时候对输入的begin+1 就可以了

res= [[]]
for i in range(begin,k):
    temp.append(nums[i])
    res.append(temp.copy())
    dfs(i+1,temp)
    temp.pop()

这里的递归最重要的方法是 递归向前,若begin 进入的值为0,则下一步就是dfs(1,temp), 由于进入的时候加上了nums[i] 所以回溯的时候必须把之前的最后一个元素给pop() 掉

思路二

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        for i in range(len(nums)+1):
            for tmp in itertools.combinations(nums, i):
                res.append(tmp)
        return res

思路三

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = [[]]
        for i in nums:
            res = res + [[i] + num for num in res]
        return res

相同的还有以下多种类似的问题

这里先把相同的问题,子集II写出来
初始的版本,未使用剪枝,只是回溯递归

   # 子集II
        # 思路同样可以使用回溯递归方法
        # 与子集I 不同的地方是此时数组内会有相同元素
        k = len(nums)
        res=[[]]
        nums.sort()
        def dfs(begin,temp,nums):
            for i in range(begin,k):  
                temp.append(nums[i])
                if temp not in res:
                    res.append(temp.copy())
                dfs(i+1,temp,nums)
                temp.pop()
        dfs(0,[],nums)
        return res

显然这样的方式速度并不快,于是就要思考如何在出现重复的情况下提前剪枝。

        nums.sort()
        self.res = []
        self.backtrack([], 0, nums, 0)
        return self.res

    def backtrack(self, sol, index, nums, pre_used):
        if index == len(nums):
            self.res.append(sol)
            return
        if not (index > 0 and nums[index] == nums[index-1] and pre_used == 0):
            pre_used = 1
            self.backtrack(sol+[nums[index]], index+1, nums, pre_used)
            pre_used = 0
        self.backtrack(sol, index+1, nums, 0)

这里的剪枝去掉了对元素的去重判断,转而在出现重复之前做剪枝处理,节省空间开支

  • 46全排列
  • 47全排列II
  • 子集II
  • 第K个排列
  • 复原IP地址
  • 组合总和
  • 组合总和2
  • 组合总和3
  • 组合

最后

以上就是鳗鱼万宝路为你收集整理的LeetCode每日一题(集合问题)78.子集的全部内容,希望文章能够帮你解决LeetCode每日一题(集合问题)78.子集所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部