回溯——6.子集

力扣题目链接

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

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

解题思路总结

  • 使用回溯法(backtracking)来解决子集问题,其核心思路是对每一个元素做两种选择:要么将其加入到当前的子集中,要么不加入,并不断递归处理剩下的元素。
  • 在每一次递归调用时,都会将当前构造的 path 加入到 result 中,确保所有可能的子集都被枚举出来。
  • 最终返回的 result 包含了所有的子集,包括空集。

完整代码如下:

python 复制代码
class Solution:
    def subsets(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result

    def backtracking(self, nums, startIndex, path, result):
        result.append(path[:])  # 收集子集,要放在终止添加的上面,否则会漏掉自己
        # if startIndex >= len(nums):  # 终止条件可以不加
        #     return
        for i in range(startIndex, len(nums)):
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)
            path.pop()
python 复制代码
class Solution:
    def subsets(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result
  • nums:输入的数组,表示需要找出其所有子集的集合。
  • result:用于存储最终结果,即所有可能的子集。
  • path:用来存储当前递归路径上选择的元素,代表一个子集。

在这个函数中,首先定义了 resultpath,分别用来存储最终所有子集的集合和当前正在构建的子集,然后调用 backtracking 函数开始回溯。backtracking 函数会从 nums 的第一个元素(下标为 0)开始递归地探索所有子集。

python 复制代码
    def backtracking(self, nums, startIndex, path, result):
        result.append(path[:])  # 收集子集
        for i in range(startIndex, len(nums)):
            path.append(nums[i])  # 选择元素加入子集
            self.backtracking(nums, i + 1, path, result)  # 递归调用
            path.pop()  # 撤销选择,回溯
2.1 result.append(path[:])
  • 这行代码表示:将当前路径 path 中的元素加入到 result 中。注意这里的 path[:] 是一个浅拷贝,确保后续对 path 的修改不会影响已经加入 result 的内容。
  • 由于任何一个时刻的 path 都可以作为一个合法的子集,因此每当进入 backtracking 函数时,无论 path 中有多少元素,都会将它作为一个子集存入 result
2.2 for 循环
  • for i in range(startIndex, len(nums)):表示从 nums 中当前的起始位置 startIndex 开始,依次选择元素加入到当前子集(即 path)中。
  • 对于每一个元素 nums[i],首先将其加入到 path 中,然后递归调用 backtracking 函数,开始探索从 i + 1 位置开始的下一个元素。
  • 递归完毕后,通过 path.pop() 将最后加入的元素删除,进行回溯,尝试其他的可能组合。
2.3 终止条件
  • 代码中没有显式的终止条件。事实上,回溯函数的退出是通过遍历 nums 数组的长度自动完成的。当 startIndex 达到 len(nums) 时,for 循环不再执行,因此递归自然结束。
  • 可以加一个显式的终止条件,但实际上没有这个必要,因为 for 循环本身已经会停止。
相关推荐
小码农<^_^>30 分钟前
优选算法精品课--滑动窗口算法(一)
算法
羊小猪~~32 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
软工菜鸡1 小时前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
AI视觉网奇1 小时前
sklearn 安装使用笔记
人工智能·算法·sklearn
JingHongB2 小时前
代码随想录算法训练营Day55 | 图论理论基础、深度优先搜索理论基础、卡玛网 98.所有可达路径、797. 所有可能的路径、广度优先搜索理论基础
算法·深度优先·图论
weixin_432702262 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
小冉在学习2 小时前
day52 图论章节刷题Part04(110.字符串接龙、105.有向图的完全可达性、106.岛屿的周长 )
算法·深度优先·图论
Repeat7152 小时前
图论基础--孤岛系列
算法·深度优先·广度优先·图论基础
小冉在学习2 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论