给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
比比两句,好久没刷题,看到这道题,脑海里愣是没想到DFS,哎,心里默念一句草泥马呀
第一种思路:
由于元素都是不重复,所以有两种选法,选或者不选这个数
class Solution {
public:
void solve(vector<vector<int>>& res,vector<int> tmp,vector<int> nums,int index)
{
//临界条件,当要处理的元素的下标超出数组范围,进行回溯
if(index >= nums.size())
{
res.push_back(tmp);
return ;
}
//不选
solve(res,tmp,nums,index+1);
//选
tmp.push_back(nums[index]);
solve(res,tmp,nums,index+1);
}
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
vector<int> tmp;
solve(res,tmp,nums,0);
return res;
}
};
第二种思路:
这里可以优化,对于第一个DFS,有部分时候并没有做任何有用的操作。首先传index=0,第一个DFS嵌套函数知道index=nums.size()后,回溯才可以处理。所以我们可以优化这些部分。
class Solution {
public:
void solve(vector<vector<int>>& res,vector<int> tmp,vector<int> nums,int index)
{
if(tmp.size()<=nums.size()){
res.push_back(tmp);
}
for(int i=index;i<nums.size();i++){
tmp.push_back(nums[i]);
solve(res,tmp,nums,i+1);
tmp.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
vector<int> tmp;
solve(res,tmp,nums,0);
return res;
}
};
第三种思路:借鉴其他人想法,
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int> > res(1);
for(int i=0;i<nums.size();i++){
int cnt=res.size();
for(int j=0;j<cnt;j++){
vector<int> tmp=res[j];
tmp.push_back(nums[i]);
res.push_back(tmp);
}
}
return res;
}
};