[LeetCode] Subsets 子集合
Given a set of distinct integers, S, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If S = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
这道求子集合的问题,由于其要列出所有结果,按照以往的经验,肯定要是要用递归来做。这道题其实它的非递归解法相对来说更简单一点,下面我们先来看非递归的解法,由于题目要求子集合中数字的顺序是非降序排列的,所有我们需要预处理,先给输入数组排序,然后再进一步处理,最开始我在想的时候,是想按照子集的长度由少到多全部写出来,比如子集长度为0的就是空集,空集是任何集合的子集,满足条件,直接加入。下面长度为1的子集,直接一个循环加入所有数字,子集长度为2的话可以用两个循环,但是这种想法到后面就行不通了,因为循环的个数不能无限的增长,所以我们必须换一种思路。我们可以一位一位的网上叠加,比如对于题目中给的例子 [1,2,3] 来说,最开始是空集,那么我们现在要处理1,就在空集上加1,为 [1],现在我们有两个自己 [] 和 [1],下面我们来处理2,我们在之前的子集基础上,每个都加个2,可以分别得到 [2],[1, 2],那么现在所有的子集合为 [], [1], [2], [1, 2],同理处理3的情况可得 [3], [1, 3], [2, 3], [1, 2, 3], 再加上之前的子集就是所有的子集合了,代码如下:
解法一:
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
vector<vector<int> > res();
sort(S.begin(), S.end());
for (int i = ; i < S.size(); ++i) {
int size = res.size();
for (int j = ; j < size; ++j) {
res.push_back(res[j]);
res.back().push_back(S[i]);
}
}
return res;
}
};
整个添加的顺序为:
[]
[1]
[2]
[1 2]
[3]
[1 3]
[2 3]
[1 2 3]
下面来看递归的解法,相当于一种深度优先搜索,参见网友 JustDoIt的博客,由于原集合每一个数字只有两种状态,要么存在,要么不存在,那么在构造子集时就有选择和不选择两种情况,所以可以构造一棵二叉树,左子树表示选择该层处理的节点,右子树表示不选择,最终的叶节点就是所有子集合,树的结构如下:
[]
/ \
/ \
/ \
[] []
/ \ / \
/ \ / \
[ ] [] [] []
/ \ / \ / \ / \
[ ] [ ] [ ] [] [ ] [] [] []
解法二:
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
vector<vector<int> > res;
vector<int> out;
sort(S.begin(), S.end());
getSubsets(S, , out, res);
return res;
}
void getSubsets(vector<int> &S, int pos, vector<int> &out, vector<vector<int> > &res) {
res.push_back(out);
for (int i = pos; i < S.size(); ++i) {
out.push_back(S[i]);
getSubsets(S, i + , out, res);
out.pop_back();
}
}
};
整个添加的顺序为:
[]
[1]
[1 2]
[1 2 3]
[1 3]
[2]
[2 3]
[3]
最后我们再来看一种解法,这种解法是 CareerCup 书上给的一种解法,想法也比较巧妙,把数组中所有的数分配一个状态,true 表示这个数在子集中出现,false 表示在子集中不出现,那么对于一个长度为n的数组,每个数字都有出现与不出现两种情况,所以共有 2n 中情况,那么我们把每种情况都转换出来就是子集了,我们还是用题目中的例子, [1 2 3] 这个数组共有8个子集,每个子集的序号的二进制表示,把是1的位对应原数组中的数字取出来就是一个子集,八种情况都取出来就是所有的子集了,参见代码如下:
| 1 | 2 | 3 | Subset | |
| 0 | F | F | F | [] |
| 1 | F | F | T | 3 |
| 2 | F | T | F | 2 |
| 3 | F | T | T | 23 |
| 4 | T | F | F | 1 |
| 5 | T | F | T | 13 |
| 6 | T | T | F | 12 |
| 7 | T | T | T | 123 |
解法三:
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
vector<vector<int> > res;
sort(S.begin(), S.end());
int max = << S.size();
for (int k = ; k < max; ++k) {
vector<int> out = convertIntToSet(S, k);
res.push_back(out);
}
return res;
}
vector<int> convertIntToSet(vector<int> &S, int k) {
vector<int> sub;
int idx = ;
for (int i = k; i > ; i >>= ) {
if ((i & ) == ) {
sub.push_back(S[idx]);
}
++idx;
}
return sub;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/78
类似题目:
参考资料:
https://leetcode.com/problems/subsets/
https://leetcode.com/problems/subsets/discuss/27288/My-solution-using-bit-manipulation
https://leetcode.com/problems/subsets/discuss/27278/C%2B%2B-RecursiveIterativeBit-Manipulation
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Subsets 子集合的更多相关文章
- [LeetCode] 78. Subsets 子集合
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
- [CareerCup] 9.4 Subsets 子集合
9.4 Write a method to return all subsets of a set. LeetCode上的原题,请参见我之前的博客Subsets 子集合和Subsets II 子集合之 ...
- [LeetCode] 90. Subsets II 子集合 II
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the ...
- LeetCode 78. Subsets(子集合)
Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not ...
- [LeetCode] 916. Word Subsets 单词子集合
We are given two arrays A and B of words. Each word is a string of lowercase letters. Now, say that ...
- LeetCode:Subsets I II
求集合的所有子集问题 LeetCode:Subsets Given a set of distinct integers, S, return all possible subsets. Note: ...
- LeetCode Subsets II (DFS)
题意: 给一个集合,有n个可能相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: 看这个就差不多了.LEETCODE SUBSETS (DFS) class Solution { publ ...
- [LeetCode] Subsets I (78) & II (90) 解题思路,即全组合算法
78. Subsets Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a ...
- [Leetcode] subsets 求数组所有的子集
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
随机推荐
- 你真的会玩SQL吗?表表达式,排名函数
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- line-height不同单位之间的区别
line-height用来设置元素的行高. 该属性会影响行框的布局.在应用到一个块级元素时,它定义了该元素中基线之间的最小距离而不是最大距离. line-height 与 font-size 的计算值 ...
- Win10 UWP系列:关于错误 0x80073CF9及一个小bug的解决
最近一直在开发XX的uwp版本,也是边摸索边做,最近遇到几个比较奇怪的问题,记录于此. 1.项目可用部署到PC,但无法部署到手机,提示以下错误: 错误 : DEP0001 : 意外错误: Instal ...
- Entity Framework 教程——概述
Entity Framework 基础 本教材将手把手教你使用entity framework,我们将使用entity framework 6.0和visual studio 2012. 以下表格是e ...
- Devexpress GridView 列中显示图片
首先将图片添加到ImageList中 添加GridView中Column void gridView1_CustomUnboundColumnData(object sender, DevExpres ...
- C# - Networkcomms
来自英国的用C#语言编写的开源的TCP/UDP网络通信框架,简单方便,性能稳定. 参考: NetworkComms官网: NetworkComms通信框架中文网: 介绍开源的.net通信框架: Ne ...
- spring+mybatis多数据源动态切换
spring mvc+mybatis+多数据源切换 选取oracle,mysql作为例子切换数据源.oracle为默认数据源,在测试的action中,进行mysql和oracle的动态切换. web. ...
- 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo
前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的话分工会更细,比如携程: 携程app = 机票频道 + 酒店频道 + 旅游频道 + ..... ...
- querySelector系列方法相比 getElementsBy 系列方法有什么区别?
querySelector 和 querySelectorAll 相比下面这些方法有什么区别? getElementsByTagName getElementsByClassName getElem ...
- BI解决方案分享:地产BI数据分析系统的建设
近几年中国地产行业发展迅猛,行业整合已成大势所趋,逐步由区域开发转变为集团化的跨地区综合开发商.然而,对于处在超常规速度发展的房地产企业来说,其面临的挑战也是超常规的.企业要在有限的资金和人力条件下, ...