LeetCode(78):子集
Medium!
题目描述:
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[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], 再加上之前的子集就是所有的子集合了。
C++解法一:
// Non-recursion
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]
下面来看递归的解法,相当于一种深度优先搜索,参见http://www.cnblogs.com/TenosDoIt/p/3451902.html,由于原集合每一个数字只有两种状态,要么存在,要么不存在,那么在构造子集时就有选择和不选择两种情况,所以可以构造一棵二叉树,左子树表示选择该层处理的节点,右子树表示不选择,最终的叶节点就是所有子集合,树的结构如下:
[]
/ \
/ \
/ \
[] []
/ \ / \
/ \ / \
[ ] [] [] []
/ \ / \ / \ / \
[ ] [ ] [ ] [] [ ] [] [] []
C++解法二:
// Recursion
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的位对应原数组中的数字取出来就是一个子集,八种情况都取出来就是所有的子集了。

C++解法三:
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;
}
};
LeetCode(78):子集的更多相关文章
- LeetCode 78. 子集(Subsets) 34
78. 子集 78. Subsets 题目描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明: 解集不能包含重复的子集. 每日一算法2019/6/6Day 34L ...
- 每日一题-——LeetCode(78)子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).输入: nums = [1,2,3]输出:[ [3], [1], [2], [1,2,3], [1,3], [2, ...
- Java实现 LeetCode 78 子集
78. 子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], ...
- [LeetCode]78. 子集(位运算;回溯法待做)
题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], ...
- LeetCode 78 - 子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3], [1], [2], [1, ...
- leetcode 78. 子集 JAVA
题目: 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], ...
- [LeetCode] 78. 子集 ☆☆☆(回溯)
描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3], [1], [2] ...
- leetcode 78. 子集(c++)
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3], [1], [2], ...
- leetcode 78子集
采用回溯法:对于例子图解执行过程如下,其中向上的分支为向下递归,向下的分支为第二次递归,因此已经push了对应的下标的值,则从根到右边连起来的路径即为组合 由于整个过程类似于二叉树的中序遍历,因此代码 ...
- LeetCode 78. 子集 C++(位运算和回溯法)
位运算 class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { ...
随机推荐
- Maven 那点事儿(转)
0. 前言 Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他. 这兄弟是干嘛的? 他就是 Maven 的创始人,人们都尊称他为“Maven 他爸”. 毋庸置疑,Jason 也 ...
- ReentrantLock(重入锁)的使用
//效果和synchronized一样,都可以同步执行,lock方法获得锁,unlock方法释放锁public class MyService { private Lock lock = new Re ...
- Springboot配置时间格式
方法一: 可以在apllication.property加入下面配置就可以 #时间戳统一转换 spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring ...
- Django中的缓存基础知识
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5 ...
- python模块-----time
说明 time模块提供各种时间相关的功能 与时间相关的模块有:time,datetime,calendar 这个模块的功能不是适用于所有的平台 这个模块中定义的大部分函数是调用C平台上的同名函数实现 ...
- Mint-UI
Mint-UI是基于Vue.js的移动端组件库 Mint-UI是Vue组件库,是使用Vue技术封装出来的成套的组件,可以无缝地和Vue项目进行集成开发 Mint UI官网 不同版本的安装 导入有两种方 ...
- proc/net/dev实时网速统计实例【转】
转自:https://blog.csdn.net/dosthing/article/details/80384541 前言 网络编程是程序连接网络拓展的基础,尤其是在物联网.互联网加等概念火热的当下, ...
- shell中的dd命令使用详解
一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...
- 题解-UOJ284 快乐游戏鸡
Problem uoj 题意大意: 一棵树,点权\(w_i\),每次玩家可以在树上行走,一条边需要\(1\)的时间,只能往儿子走.每次游戏需要从\(s\)到\(t\). 玩家有一个总死亡次数,初始为\ ...
- 题解-TIOJ1905 最理想的身高差
Problem 题目原型 题目大意:求区间最小差值 序列长度\(1e5\),询问\(2e5\) Solution 总体思路就是找出所有可能作为答案的点对,用资料结构_(:зゝ∠)_维护,然后询问 至于 ...