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 解题报告的更多相关文章

  1. LeetCode: Permutations 解题报告

    Permutations Given a collection of numbers, return all possible permutations. For example,[1,2,3] ha ...

  2. 【LeetCode】78. Subsets 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 回溯法 日期 题目地址:https://leet ...

  3. 【LeetCode】698. Partition to K Equal Sum Subsets 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...

  4. 【LeetCode】916. Word Subsets 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/word-sub ...

  5. leetcode—Palindrome 解题报告

    1.题目描述 Given a string s, partition s such that every substring of the partition is a palindrome. Ret ...

  6. LeetCode C++ 解题报告

    自己做得LeetCode的题解,使用C++语言. 说明:大多数自己做得,部分参考别人的思路,仅供参考; GitHub地址:https://github.com/amazingyyc/The-Solut ...

  7. C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告

    剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...

  8. LeetCode: Triangle 解题报告

    Triangle Given a triangle, find the minimum path sum from top to bottom. Each step you may move to a ...

  9. LeetCode: isSameTree1 解题报告

    isSameTree1 Given two binary trees, write a function to check if they are equal or not. Two binary t ...

随机推荐

  1. P1939【模板】矩阵加速(数列)

    P1939[模板]矩阵加速(数列)难受就难受在a[i-3],这样的话让k=3就好了. #include<iostream> #include<cstdio> #include& ...

  2. where field in

    SELECT * FROM xx  WHERE field IN ('11','22','33');

  3. [BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky

    思路: 用主席树维护并查集森林,每次连接时新增结点. 似乎并不需要启发式合并,我随随便便写了一个就跑到了3674第一页?3673是这题的弱化版,本来写个暴力就能过,现在借用加强版的代码(去掉异或),直 ...

  4. window7 更改电脑黑屏时间

    无废话--------------------Window7 更改电脑黑屏时间,步骤如下: 1.进入‘控制面板’,通过开始页面或通过计算机我的电脑中的打开‘控制面板’都可以打开. 2.系统与安全类别下 ...

  5. ELASTIC 动态修改配置API

    工作中使用ELASTIC,我们常有需要修改的配置项,但有时又不想重启elastic,这时候就需要elasticsearch内置的修改集群配置API上场了. 这个API非常的简单. curl -XPUT ...

  6. [原创]H5前端性能测试工具介绍

    [原创H5前端性能测试工具介绍 一 网络抓包工具 网络抓包工具选择原则,可以捕获网络请求,抓取具体请求信息流,同时可以针对网络请包进行修改或拦截: 1.Fiddler(推荐) 2.Charles(推荐 ...

  7. [Beego模型] 二、CRUD 操作

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

  8. event对象中 target和currentTarget 属性的区别。

    首先本质区别是: event.target返回触发事件的元素 event.currentTarget返回绑定事件的元素

  9. AngularJS中的$http缓存以及处理多个$http请求

    在AngularJS的实际项目中,经常需要处理多个$http请求,每个$http请求返回一个promise,我们可以把多个promise放到$q.all()方法接受的一个数组实参中去. ■ 处理多个$ ...

  10. android:ListView bbs Demo

    我们制 作的 message_left.9.png 可以作为收到消息的背景图,那么毫无疑问你还需要再制作一张 message_right.9.png 作为发出消息的背景图. 图片都提供好了之后就可以开 ...