17. 子集

中文
English

给定一个含不同整数的集合,返回其所有的子集。

样例

样例 1:

输入:[0]
输出:
[
[],
[0]
]

样例 2:

输入:[1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

挑战

你可以同时用递归与非递归的方式解决么?

注意事项

子集中的元素排列必须是非降序的,解集必须不包含重复的子集。

时间复杂度是O(2^n),本质就是在做二叉树的dfs。[1,2,3]举例:

root

/   \

不选中1  选中1

/    \           /      \

不选中2  选中2  不选中2  选中2

。。。。。

使用dfs记录遍历路径即可。

class Solution:
"""
@param nums: A set of numbers
@return: A list of lists
"""
def subsets(self, nums):
# write your code here
path, results = [],[]
self.helper(sorted(nums), 0, path, results)
return results def helper(self, nums, index, path, results):
if index == len(nums):
results.append(list(path))
return path.append(nums[index])
self.helper(nums, index+1, path, results) path.pop()
self.helper(nums, index+1, path, results)

第二种写法是使用位运算,也比较直观,代码很容易写出来:

class Solution:
"""
@param nums: A set of numbers
@return: A list of lists
"""
def subsets(self, nums):
# write your code here
nums = sorted(nums)
n = len(nums)
results = []
for i in range(1<<n):
results.append(self.get_num(nums, i, n))
return results def get_num(self, nums, num, cnt):
result = []
for i in range(cnt):
if num & (1<<i):
result.append(nums[i])
return result

第三种写法是使用for dfs写法,看下面的图,以【1,2,3】为例:

root (path=[])

|

----------------------------------------

|                                   |                                  |

1                                   2                                 3

/   \                                 |

2      3                               3

/

3

在遍历上述树的过程中将path全部记录下来(path不用走到叶子节点):

class Solution:
"""
@param nums: A set of numbers
@return: A list of lists
"""
def subsets(self, nums):
# write your code here
nums = sorted(nums)
path, result = [], []
self.dfs(nums, 0, path, result)
return result def dfs(self, nums, index, path, result):
result.append(list(path)) if index == len(nums):
return for i in range(index, len(nums)):
path.append(nums[i])
self.dfs(nums, i+1, path, result)
path.pop()

含有重复元素的子集问题,例如【1,2,2,3】

root (path=[])

|

----------------------------------------

|                                   |                  |                |

1                                   2                2(重复)       3

/   \                               /  \              |

2      3                           2     3            3

/ \                                  |

2    3                                3

|

3

又例如【1,1,2,3】

root (path=[])

|

----------------|-------------------------

|                           1(重复)         |                           |

1                         / \                   2                          3

/ |  \                    2    3                 |

1    2   3                 |                       3

/ \   |                      3

2   3  3

|

3

所以代码如下:

class Solution:
"""
@param nums: A set of numbers.
@return: A list of lists. All valid subsets.
"""
def subsetsWithDup(self, nums):
# write your code here
nums = sorted(nums)
path, result = [], []
self.dfs(nums, 0, path, result)
return result def dfs(self, nums, index, path, result):
result.append(list(path)) for i in range(index, len(nums)):
if i > 0 and nums[i] == nums[i-1] and i > index:
continue path.append(nums[i])
self.dfs(nums, i+1, path, result)
path.pop()

dfs 排列组合——找所有子集(重复元素和不重复元素)的更多相关文章

  1. Codeforces 991E. Bus Number (DFS+排列组合)

    解题思路 将每个数字出现的次数存在一个数组num[]中(与顺序无关). 将出现过的数字i从1到num[i]遍历.(i from 0 to 9) 得到要使用的数字次数数组a[]. 对于每一种a使用排列组 ...

  2. DFS排列组合问题

    这四个使用DFS来求解所有组合和排列的例子很有代表性,这里做一个总结: 1.不带重复元素的子集问题 public ArrayList<ArrayList<Integer>> s ...

  3. [leetcode] 题型整理之排列组合

    一般用dfs来做 最简单的一种: 17. Letter Combinations of a Phone Number Given a digit string, return all possible ...

  4. 排列 && 组合

    最近编程经常遇到需要 排列&&组合(求子集) 的问题:遂整理一下. 1. 数字的排列与组合(递归):O(n!),O(nC(n,k)) * O(n) #include <stdio ...

  5. DFS实现排列组合

    所谓排列,是指从给定的元素序列中依次取出元素,需要考虑取出顺序.比如,取出元素3, 5,因取出顺序的不同,则形成的序列{3, 5}与{5, 3}是不同的排列序列.对于长度为n的元素序列取出k个元素,则 ...

  6. 面试题: 已知一个含有n个不同元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)

    TX面试题2: 已知一个含有n个元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的) 题目分析, 为了便于说明,不妨将问题简化一下: 已知一个盒子中有n个不同的球,分别标记为{a1,a2,. ...

  7. dfs 全排列 使用交换——含重复元素和非重复元素

    15. 全排列 中文 English 给定一个数字列表,返回其所有可能的排列. 样例 样例 1: 输入:[1] 输出: [ [1] ] 样例 2: 输入:[1,2,3] 输出: [ [1,2,3], ...

  8. PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?

    首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...

  9. N个数组中所有元素的排列组合(笛卡尔积)算法

    (1)N个数组对象中所有元素排列组合算法 private List<List<Object>> combineAlg(List<Object[]> nArray) ...

随机推荐

  1. [Gamma阶段]测试报告

    [Gamma阶段]测试报告 博客目录 测试方法及过程 在正式发布前,为检验后端各接口功能的正确性,后端服务器对压力的耐受程度,以及前端各页面.功能的运行情况,我们对我们的服务器及小程序进行了多种测试. ...

  2. C# 激活主窗口

    今天同学跟我说了一个bug,虽然很简单,但还是记录一下,也好让我养成写东西的习惯. C# windows form 程序中,发生某个事件时,需要自动弹出一个窗口,提示用户,并等待用户输入进行处理. 如 ...

  3. exports与module.exports的区别,以及export与export.defult的区别

    在 JS 模块化编程的模块引入上, 主要有两种方式: CommonJS 模块标准 ES6 moduel 特性 1. CommonJS 模块引入:require() 模块导出:exports 或者 mo ...

  4. 2-3-4树(jdk8的TreeMap的红黑树)

    2-3树:插入变成2个节点正常插,变成3个节点就要提升中间节点和分裂子节点,满足:要么没有子节点,要么2个子节点,要么3个子节点. 2-3-4树:插入变成2个不动,插入变成3个不动,插入变成4个提升原 ...

  5. Linux内核引用计数器kref结构

    1.前言 struct kref结构体是一个引用计数器,它被嵌套进其它的结构体中,记录所嵌套结构的引用计数.引用计数用于检测内核中有多少地方使用了某个对象,每当内核的一个部分需要某个对象所包含的信息时 ...

  6. 设置KAFKA

    让我们继续下载并设置Kafka,启动zookeeper,集群,生产者和消费者.   要下载Kafka,请参阅此链接  http://kafka.apache.org/downloads.html 下载 ...

  7. 50道Java线程面试题分析及答案

    下面是Java线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程 ...

  8. .net Dapper 实践系列(5) ---事务编辑(Layui+Ajax+Dapper+MySQL)

    目录 写在前面 实践步骤 写在前面 上一小节,我们总结了根据Id查询多表数据,最后返回Json对象给前台的例子.接下来,在这一小节我们要实现多表编辑的操作. 实践步骤 因为上一小节以及创建了Edit视 ...

  9. 接口例_龟车赛跑_Java

    此例演示java中接口的一般用法. 屋子里有一群程序员,每个人在写着自己的类,共同构建一个世界. 项目经理突然出现:“打扰大家一下,公司决定举办一个竞速比赛,你们写的类都可以参加.为了比赛的顺利进行, ...

  10. typing类型注解库

    简介 动态语言的灵活性使其在做一些工具,脚本时非常方便,但是同时也给大型项目的开发带来了一些麻烦. 自python3.5开始,PEP484为python引入了类型注解(type hints),虽然在p ...