文章目录
- 78. 子集
- 题目描述
- 回溯算法
78. 子集
题目描述
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
提示:
- 1 <= nums.length <= 10
- -10 <= nums[i] <= 10
- nums 中的所有元素 互不相同
回溯算法
// 78. 子集
class Solution {
public:// 主函数,接受一个整数数组作为输入,返回该数组所有可能的子集vector<vector<int>> subsets(vector<int>& nums) {backstracking(nums, 0); // 开始回溯算法,从索引0开始return result; // 返回所有找到的子集}private:vector<vector<int>> result; // 用于存储所有可能的子集vector<int> path; // 用于存储当前路径(即当前构造的子集)// 回溯函数void backstracking(vector<int>& nums, int start) {// 每次进入函数,先将当前路径添加到结果中// 因为子集也包括空集和包含部分元素的集合result.push_back(path);// 如果start等于nums的大小,说明已经处理完所有元素,返回if(start == nums.size()) {return;}// 从start开始遍历nums中的每个元素for(int i = start; i < nums.size(); i++) {// 将当前元素添加到路径中path.push_back(nums[i]);// 递归调用,i+1为下一次递归的起点backstracking(nums, i + 1);// 回溯:从路径中移除刚才添加的元素,尝试下一个元素path.pop_back();}}
};
这段代码实现了一个经典的回溯算法框架,用于解决子集生成问题。它首先定义了一个result
变量来存储所有可能的子集,以及一个path
变量来存储当前正在构建的子集。backstracking
是一个递归函数,它试图通过遍历数组nums
的每个元素,并在每一步中决定是否将当前元素加入到当前路径path
中,从而构建出所有可能的子集。
关键点在于,每次进入backstracking
函数时,无论当前路径path
的内容如何,都将其添加到结果集result
中。这确保了包括空集在内的所有子集都被收集。然后,通过递归地调用自身并逐步增加start
参数,算法确保每个元素都有机会被包括在子集中,同时避免了重复。最后,通过在每次递归后从path
中移除最近添加的元素,这个算法能够回溯并探索所有可能的子集组合。