LeetCode78-子集详解

    往期博客:

Leetcode1-两数之和详解

Leetcode2-两数相加代码详解

Leetcode20-有效的括号详解

Leetcode21-合并两个有序链表详解

Leetcode22-有效括号生成详解

Leetcode24-两两交换链表中的节点详解

Leetcode27-移除元素详解

Leetcode46-全排列详解

Leetcode49-字母异位分组详解

Leetcode53-最大子数组和详解

Leetcode56-合并区间详解

LeetCode57-插入区间详解

Leetcode77-组合详解


目录

题目

示例

解析

扩展法

递归法

深度优先算法

代码

排序法

回溯法

深度优先算法


题目

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

题目分析:

已知:整数数组nums

目的:找所有子集

要求:返回所有子集,不能重复


示例

示例1

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例2

输入:nums = [0]
输出:[[],[0]]

解析

扩展法

扩展法的思路就像垒金字塔一样,一层一层的将所有子集找出来,扩展法首先从一个空子集开始,将空子集作为金字塔的第一层即塔尖位置,每次遍历数组中的元素,将元素添加上一层的数组中作为新的列表作为金字塔的第二层,依次遍历数组元素,直到遍历完所有元素为止。

根据具体示例进行分析。

如图所示,首先创建一个空列表,遍历nums第一个元素为1,将元素1加入空列表构成另一个新子集[1],在遍历第二个元素为2,将元素2加入已有的 [] 和 [1] 两个子集中形成新子集 [2] 和 [1,2],再遍历第三个元素为3,将元素3添加到已有的 [] 、 [1] 、 [2] 和 [1,2] 子集中构成新的子集 [3] 、 [1,3] 、 [2,3] 和 [1,2,3],至此所有自己已经全部找到了。

递归法

我们观察结果可以发现,数组[1,2,3]的所欲子集可以按长度进行划分,分别由有长度为0、长度为1、长度为2和长度为3的子集,所以我们可以按长度进行查找,并且在递归的过程中隐藏两个剪枝条件:长度和重复。

例如对于数组[1,2,3],长度为0的只有一个空子集

长度为1的包含[1][2][3],即当子集长度达到1时进行回溯,绿色箭头表示回溯过程

 长度为2的包含[1,2][1,3][2,3],即子集长度达到2时进行回溯,绿色箭头表示回溯过程

长度为2的包含[1,2,3],即子集长度达到3时进行回溯,绿色箭头表示回溯过程

深度优先算法

深度优先算法也是要进行递归的过程,但它和上述说的回溯方法主要对的不同是,深度优先算法是在一条路上坚持到底,先按深度进行查找,直到当前路径无路可走时再探索新的路径。

例如对于数组[1,2,3],第一路就是以1开始的路径,此时的子集分别为[1][1,2][1,2,3]

 此时这个方向已无路可走,变返回一次,探索新路,出现新的子集[1,3]

 再返回,开辟2开始的路径,形成新的子集[2][2,3]


代码

排序法

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result = [[]]

        for num in nums:
            temp = []
            for cur in result:
                temp.append(cur+[num])
            for t in temp:
                result.append(t)
        return result

回溯法

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result = [[]]

        for i in range(1, len(nums) + 1):
            self.backtracking(nums, result, i, 0, [])
        return result

        def backtracking(self, nums, result, length, index, subset):
            if len(subset) == length:
                result.append(subset[:])
                return

            for i in range(index, len(nums)):
                subset.append(nums[i])
                self.backtracking(nums, result, length, i+1, subset)
                subset.pop()

深度优先算法

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result = []
        self.dfs(nums, result, 0, [])
        return result

    def dfs(self, nums, result, index, subset):
        result.append(subset[:])
        if index == len(nums):
            return
        for i in range(index, len(nums)):
            subset.append(nums[i])
            self.dfs(nums, result, i+1, subset)
            subset.pop()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值