力扣 leetcode 78. 子集
问题描述
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
提示:
- 1 <= nums.length <= 10
- -10 <= nums[i] <= 10
- nums 中的所有元素 互不相同
示例
示例 1:
输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
解题思路
这里考察的是递归的基本用法,我们要注意保存上一次递归时的状态,以及考虑递归终止条件。
这里保存上一次递归时的状态有两个作用,一是为了记录结果;二是为了避免重复添加。
递归的终止条件可以根据子数组的长度来决定。
class Solution {
public:
// 递归求解
void pushItem(vector<vector<int>>& res, vector<int>& nums, vector<bool>& visited, int idx, int step){
if(step){ // step控制此时子数组的长度
step--;
// i 从idx开始,可以避免重复
for(int i = idx; i < nums.size() - step; i++){
if(!visited[i]){
visited[i] = true;
// 注意,此时下一次for循环的i从 i + 1开始,避免出现[nums[0], nums[1]],[nums[1], nums[0]]的情况
pushItem(res, nums, visited, i + 1, step);
visited[i] = false;
}
}
}
else{
vector<int> r;
for(int i = 0; i < nums.size(); i++){
if(visited[i]){
r.push_back(nums[i]);
}
}
// 添加结果
res.push_back(r);
}
}
vector<vector<int>> subsets(vector<int>& nums) {
const int n = nums.size();
if(!n){
return {nums};
}
// 结果中至少有一个{}
vector<vector<int>> res(1, vector<int> {});
vector<bool> visited(n, false);
int idx = 0;
// 这里将长度为1到n的子数组都添加
for(int i = 1; i <= n; i++){
pushItem(res, nums, visited, idx, i);
}
return res;
}
};
本文来自博客园,作者:greatestchen},转载请注明原文链接:https://www.cnblogs.com/greatestchen/p/16964747.html