1. 题目解析
题目链接:78. 子集
这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。
2.算法原理
为了生成一个给定数组 nums
的所有子集,我们可以利用一种称为回溯(backtracking)的算法策略。回溯法通过递归的方式,在每一步选择是否将当前元素包含在子集中,并继续处理后续的元素。由于每个元素都可以被选择或不选择,因此总共会产生 2^n
个子集(其中 n
是数组 nums
的长度)。
算法步骤:
- 定义递归函数:
- 函数名:
dfs
(深度优先搜索) - 参数:
res
:存储所有子集的二维向量ans
:当前正在构建的子集nums
:输入数组step
:当前处理的元素下标
- 返回值:无(函数通过修改参数
res
来返回结果)
- 函数名:
- 递归结束条件:
- 当
step
等于nums
的长度时,表示已经处理了数组中的所有元素,此时将ans
加入到res
中,并返回。
- 当
- 递归过程:
- 在每一步,都有两种选择:
- 不选择当前元素:保持
ans
不变,递归调用dfs
函数处理下一个元素(step + 1
)。 - 选择当前元素:将
nums[step]
添加到ans
的末尾,然后递归调用dfs
函数处理下一个元素。在递归返回后,需要从ans
中移除最后添加的元素(回溯),以确保下一次递归调用时ans
的状态是正确的。
- 不选择当前元素:保持
- 在每一步,都有两种选择:
- 结果返回:
- 递归结束后,
res
将包含nums
的所有子集。
- 递归结束后,
3.代码编写
class Solution {
vector<vector<int>> ret;
vector<int> path;
public:
vector<vector<int>> subsets(vector<int>& nums) {
dfs(nums, 0);
return ret;
}
void dfs(vector<int>& nums, int pos) {
ret.push_back(path);
for (int i = pos; i < nums.size(); i++) {
path.push_back(nums[i]);
dfs(nums, i + 1);
path.pop_back(); // 恢复现场
}
}
};
The Last
嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。
觉得有点收获的话,不妨给我点个赞吧!
如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~