LeetCode: Subsets 解题报告
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],
[]
]
SOLUTION 1:
使用九章算法的模板:
递归解决。
1. 先对数组进行排序。
2. 在set中依次取一个数字出来即可,因为我们保持升序,所以不需要取当前Index之前的数字。
TIME: 227 ms
public class Solution {
public List<List<Integer>> subsets(int[] S) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (S == null) {
return ret;
}
Arrays.sort(S);
dfs(S, , new ArrayList<Integer> (), ret);
return ret;
}
public void dfs(int[] S, int index, List<Integer> path, List<List<Integer>> ret) {
ret.add(new ArrayList<Integer>(path));
for (int i = index; i < S.length; i++) {
path.add(S[i]);
dfs(S, i + , path, ret);
path.remove(path.size() - );
}
}
}
SOLUTION 2:
在Solution 1的基础之上,使用Hashmap来记录中间结果,即是以index开始的所有的组合,希望可以加快运行效率,最后时间:
TIME:253 ms.
实际结果与预期反而不一致。原因可能是每次新组装这些解也需要耗费时间
// Solution 3: The memory and recursion.
public List<List<Integer>> subsets(int[] S) {
//
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (S == null) {
return ret;
} Arrays.sort(S);
return dfs3(S, , new HashMap<Integer, List<List<Integer>>>());
} public List<List<Integer>> dfs3(int[] S, int index, HashMap<Integer, List<List<Integer>>> map) {
int len = S.length; if (map.containsKey(index)) {
return map.get(index);
} List<List<Integer>> ret = new ArrayList<List<Integer>>();
List<Integer> pathTmp = new ArrayList<Integer>();
ret.add(pathTmp); for (int i = index; i < len; i++) {
List<List<Integer>> left = dfs3(S, i + , map);
for (List<Integer> list: left) {
pathTmp = new ArrayList<Integer>();
pathTmp.add(S[i]);
pathTmp.addAll(list);
ret.add(pathTmp);
}
} map.put(index, ret);
return ret;
}
SOLUTION 3:
相当牛逼的bit解法。基本的想法是,用bit位来表示这一位的number要不要取,第一位有1,0即取和不取2种可能性。所以只要把0到N种可能
都用bit位表示,再把它转化为数字集合,就可以了。
Ref: http://www.fusu.us/2013/07/the-subsets-problem.html
There are many variations of this problem, I will stay on the general problem of finding all subsets of a set. For example if our set is [1, 2, 3] - we would have 8 (2 to the power of 3) subsets: {[], [1], [2], [3], [1, 2], [1, 3], [1, 2, 3], [2, 3]}. So basically our algorithm can't be faster than O(2^n) since we need to go through all possible combinations.
There's a few ways of doing this. I'll mention two ways here - the recursive way, that we've been taught in high schools; and using a bit string.
Using a bit string involves some bit manipulation but the final code can be found easy to understand. The idea is that all the numbers from 0 to 2^n are represented by unique bit strings of n bit width that can be translated into a subset. So for example in the above mentioned array we would have 8 numbers from 0 to 7 inclusive that would have a bit representation that is translated using the bit index as the index of the array.
|
Nr |
Bits |
Combination |
|
0 |
000 |
{} |
|
1 |
001 |
{1} |
|
2 |
010 |
{2} |
|
3 |
011 |
{1, 2} |
|
4 |
100 |
{3} |
|
5 |
101 |
{1, 3} |
|
6 |
110 |
{2, 3} |
|
7 |
111 |
{1, 2, 3} |
public class Solution {
public List<List<Integer>> subsets(int[] S) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
if (S == null || S.length == ) {
return ret;
}
int len = S.length;
Arrays.sort(S);
// forget to add (long).
long numOfSet = (long)Math.pow(, len);
for (int i = ; i < numOfSet; i++) {
// bug 3: should use tmp - i.
long tmp = i;
ArrayList<Integer> list = new ArrayList<Integer>();
while (tmp != ) {
// bug 2: use error NumberOfTrailingZeros.
int indexOfLast1 = Long.numberOfTrailingZeros(tmp);
list.add(S[indexOfLast1]);
// clear the bit.
tmp ^= ( << indexOfLast1);
}
ret.add(list);
}
return ret;
}
}
性能测试:
1. when SIZE = 19:
Subset with memory record: 14350.0 millisec.
Subset recursion: 2525.0 millisec.
Subset Iterator: 5207.0 millisec.
表明带memeory的性能反而不行。而iterator的性能也不并不如。
2. size再继续加大时,iterator的会出现Heap 溢出的问题,且速度非常非常慢。原因不是太懂。
GITHUB: https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/dfs/Subsets.java
LeetCode: Subsets 解题报告的更多相关文章
- LeetCode: Permutations 解题报告
Permutations Given a collection of numbers, return all possible permutations. For example,[1,2,3] ha ...
- 【LeetCode】78. Subsets 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 回溯法 日期 题目地址:https://leet ...
- 【LeetCode】698. Partition to K Equal Sum Subsets 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...
- 【LeetCode】916. Word Subsets 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/word-sub ...
- leetcode—Palindrome 解题报告
1.题目描述 Given a string s, partition s such that every substring of the partition is a palindrome. Ret ...
- LeetCode C++ 解题报告
自己做得LeetCode的题解,使用C++语言. 说明:大多数自己做得,部分参考别人的思路,仅供参考; GitHub地址:https://github.com/amazingyyc/The-Solut ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- LeetCode: Triangle 解题报告
Triangle Given a triangle, find the minimum path sum from top to bottom. Each step you may move to a ...
- LeetCode: isSameTree1 解题报告
isSameTree1 Given two binary trees, write a function to check if they are equal or not. Two binary t ...
随机推荐
- HDU 2612 find a way 【双BFS】
<题目链接> 题目大意:两个人分别从地图中的Y 和 M出发,要共同在 @ 处会面(@不止有一处),问这两个人所走距离和的最小值是多少. 解题分析: 就是对这两个点分别进行一次BFS,求出它 ...
- 几个文本处理工具的简单使用(wc,cut,sort,uniq,diff和patch)
wc wc命令用于报告文本文件的一些统计计数,例如行数.单词数.字节数等. 语法如下. wc [OPTION]... [FILE]... wc [OPTION]... --files0-from=F ...
- Scratch儿童项目式编程--接球游戏 Scratch children program programming - catching a ball
Scratch儿童项目式编程--接球游戏 Scratch children program programming - catching a ball 作者:韩梦飞沙 Author:han_meng_ ...
- 51Nod1577 异或凑数 线性基 构造
国际惯例的题面:异或凑出一个数,显然是线性基了.显然我们能把区间[l,r]的数全都扔进一个线性基,然后试着插入w,如果能插入,则说明w不能被这些数线性表出,那么就要输出"NO"了. ...
- [CF896C]Willem, Chtholly and Seniorious(珂朵莉树)
https://www.cnblogs.com/WAMonster/p/10181214.html 主要用于支持含有较难维护的区间操作与查询的问题,要求其中区间赋值操作(assign())是纯随机的. ...
- HDU.4352.XHXJ's LIS(数位DP 状压 LIS)
题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...
- BZOJ.3575.[HNOI2014]道路堵塞(最短路 动态SPFA)
题目链接 \(Description\) 给你一张有向图及一条\(1\)到\(n\)的最短路.对这条最短路上的每条边,求删掉这条边后\(1\)到\(n\)的最短路是多少. \(Solution\) 枚 ...
- TCP/IP通信协议
TCP/IP 是用于 Internet 的通信协议. 一.什么是 TCP/IP 1.TPC/IP 是供已连接 Internet 的计算机进行通信的协议: 2.TCP(Transmission Cont ...
- only_full_group_by的注意事项
only_full_group_by的注意事项 使用这个就是使用和oracle一样的group 规则, select的列都要在group中,或者本身是聚合列(SUM,AVG,MAX,MIN) 才行
- asp.net c#并行调用service层代码
public ActionResult Home(AdviserSearchModel model) { //顾问列表需要的当前城市的下级地区 var ip = "117.82.196.19 ...