17 子集
原题网址: https://www.lintcode.com/zh-cn/problem/subsets/
给定一个含不同整数的集合,返回其所有的子集
注意事项
子集中的元素排列必须是非降序的,解集必须不包含重复的子集
您在真实的面试中是否遇到过这个题?
Yes
样例
如果 S = [1,2,3]
,有如下的解:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
挑战
你可以同时用递归与非递归的方式解决么?
标签
方法1.非递归
要求子集中元素排列升序,可以将原数组升序排列,然后依次加入到结果数组中。
举个例子,输入数组【1,2,3】,首先将【1】push到result中;
然后从原数组中取出元素2,创建临时数组temp1=【1】,将2 push到temp1中得到【1,2】,将temp1 push到result中,再将【2】本身push到result中,此时result中有【1】,【1,2】,【2】;
从原数组中取出元素3,创建临时数组依次等于【1】,【1,2】,【2】,将3 分别push进去得到【1,3】,【1,2,3】,【2,3】,再将临时数组push到result中,再将【3】本身push到result中,over;
最后一定记得再push一个空数组到result中。
AC代码:
class Solution { public: /** * @param nums: A set of numbers * @return: A list of lists */ vector<vector<int>> subsets(vector<int> &nums) { // write your code here vector<vector<int>> result; if (nums.empty()) { result.push_back(nums); return result; } sort(nums.begin(),nums.end()); vector<int> first; first.push_back(nums[0]); result.push_back(first); for (int i=1;i<(int)nums.size();i++) { int size1=result.size(); for (int j=0;j<size1;j++) { vector<int> temp1= result[j]; temp1.push_back(nums[i]); result.push_back(temp1); } vector<int> temp2; temp2.push_back(nums[i]); result.push_back(temp2); } vector<int> nul; result.push_back(nul); return result; } };
方法2.递归 参考 https://www.cnblogs.com/felixfang/p/3775712.html 与 https://www.cnblogs.com/eudiwffe/p/6558744.html
思路:所谓子集,就是包含原集合中的一些元素,不包含另一些元素。如果单独看某一个元素,它都有两种选择:"被包含在当前子集中"和"不被包含在当前子集中",对于元素个数为n、且不含重复元素的S,子集总数是2n。因此我们可以遍历S的所有元素,然后用递归考虑每一个元素包含和不包含的两种情况。
深度优先搜索。
图源:https://blog.csdn.net/aphysia/article/details/77849042
AC代码:
class Solution { public: /** * @param nums: A set of numbers * @return: A list of lists */ vector<vector<int>> subsets(vector<int> &nums) { // write your code here vector<vector<int>> result; if (nums.empty()) { result.push_back(nums); return result; } sort(nums.begin(),nums.end()); vector<int> v; subsetCore(nums,v,0,result); return result; } void subsetCore(vector<int> &nums,vector<int> &v,int pos,vector<vector<int>> &result ) { if (pos==nums.size())//遍历所有元素,即只要POS还指向某个元素,就要进行是否在当前子集的判断; { result.push_back(v); return ; } vector<int> v2(v); //v和v2是当前正在生成的子集; v.push_back(nums[pos]);//v包含当前元素; subsetCore(nums,v,pos+1,result); subsetCore(nums,v2,pos+1,result); //v2不包含当前元素; } };
其他思路:https://www.jianshu.com/p/557788c1dcc1 没太看懂,可结合 http://www.cnblogs.com/springfor/p/3879830.html?utm_source=tuicool&utm_medium=referral 理解