刚吃完中饭,就马不停蹄的奔向实验室刷了一道题,下面就和大家分享一下经验吧!
题目如下:
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
题意分析:
给定一个包含不同整数的nums,请返回其所有的子集(空集也算,但重复子集不算)。
方法一(递归回溯法)
其实求得一个集合的所有子集可以看做是求组合数的递归方法但不带递归终止条件,于是理所当然可以参考“https://blog.csdn.net/Vensmallzeng/article/details/96478481”中的方法一。
解题代码如下:
class Solution{
public:
vector<vector<int>> subsets(vector<int>& nums){
vector<vector<int>> res;
vector<int> temp;
if(nums.size()==0) return {{}};
sort(nums.begin(), nums.end());
Findsubsets(nums, 0, temp, res);
return res;
}
void Findsubsets(vector<int>& nums, int start, vector<int>& temp, vector<vector<int>>& res){
//此处没有人为给定递归终止条件
res.push_back(temp);
for (int i = start; i < nums.size(); ++i) {
temp.push_back(nums[i]);
Findsubsets(nums, i+1, temp, res);
temp.pop_back();
}
}
};
提交后的结果如下:
方法二(非递归法)
因为题目要求所得子集中元素的顺序是升序排列的,所有先需要对给定nums排序然后再进一步处理。解决本题的思路是,将nums中的元素一位一位的往已有子集合中添加并且每添加完一位元素就要更新一次res结果。
举子例子:针对题目中给的例子[1,2,3],最开始res中只有一个为空集的子集,外层第一次for循环在空集上加1得到 [1],于是更新一次res结果得到两个子集[]和[1],外层第二次for循环在res中的子集上分别加2可以得到[2],[1, 2],于是更新一次res结果得到四个子集[], [1], [2], [1, 2],同理,外层第三次for循环在res中的子集上分别加3并更新res,可得八个子集[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]。
解题代码如下:
class Solution{
public:
vector<vector<int>> subsets(vector<int>& nums){
vector<vector<int>> res {{}};
for (int i = 0; i < nums.size(); ++i) {
int size = res.size();
for (int j = 0; j < size; ++j) {
res.push_back(res[j]);
res.back().push_back(nums[i]);
}
}
return res;
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。