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. C++语言实现-邻接矩阵

    一. 图的概念 图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合.在图中的数据元素,我们称之为顶点( ...

  2. POJ 1182 食物链 【带权并查集】

    <题目链接> 题目大意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我 ...

  3. Mongodb - 二进制安装

    0.概述 mongodb版本:4.0.2 linux版本:redhat 6.5 安装方式:二进制安装 1.关闭防火墙 /etc/init.d/iptables status/etc/init.d/ip ...

  4. 【java并发核心二】Exchanger的使用

    类 Exchanger 的功能可以使2个线程之间传输数据,比生产者/消费者模式方便. Exchanger类的结构很简单,重点就是exchange()方法. exchange()方法是阻塞执行的,可以设 ...

  5. 4572: [Scoi2016]围棋 轮廓线DP KMP

    国际惯例的题面:这种题目显然DP了,看到M这么小显然要状压.然后就是具体怎么DP的问题.首先我们可以暴力状压上一行状态,然后逐行转移.复杂度n*3^m+3^(m*2),显然过不去. 考虑状态的特殊性, ...

  6. 洛谷.1110.[ZJOI2007]报表统计(Multiset)

    题目链接 主要思路 /* 其实只需要multiset即可 对于询问1,删除.插入差值,输出最小元素 对于询问2,插入后用前驱后继更新 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一 ...

  7. 潭州课堂25班:Ph201805201 爬虫基础 第七课 Python与常见加密方式 (课堂笔记)

    打开图形界面  18版 Python与常见加密方式 前言 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes. 所以当我们在Python中进行加密操作的时 ...

  8. webstorm激活方法

    安装完成后,打开 WebStorm, 在打开的 License Activation 窗口中选择第三个选项: License server. 在输入框输入网址即可 最新网址: https://s.tu ...

  9. oracle级联删除

    oracle级联删除可以使用触发器来实现,但是比较麻烦,最简单的就是直接建立表的主外键关系,给列设置级联删除. ------创建了CLASS表,并设置ID字段为主键. -- Create table ...

  10. 根据 train_test.prototxt文件生成 deploy.prototxt文件

    本文参考博文 (1)介绍 *_train_test.prototxt文件与 *_deploy.prototxt文件的不同:http://blog.csdn.net/sunshine_in_moon/a ...