dfs 排列组合——找所有子集(重复元素和不重复元素)
17. 子集
给定一个含不同整数的集合,返回其所有的子集。
样例
样例 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 排列组合——找所有子集(重复元素和不重复元素)的更多相关文章
- Codeforces 991E. Bus Number (DFS+排列组合)
解题思路 将每个数字出现的次数存在一个数组num[]中(与顺序无关). 将出现过的数字i从1到num[i]遍历.(i from 0 to 9) 得到要使用的数字次数数组a[]. 对于每一种a使用排列组 ...
- DFS排列组合问题
这四个使用DFS来求解所有组合和排列的例子很有代表性,这里做一个总结: 1.不带重复元素的子集问题 public ArrayList<ArrayList<Integer>> s ...
- [leetcode] 题型整理之排列组合
一般用dfs来做 最简单的一种: 17. Letter Combinations of a Phone Number Given a digit string, return all possible ...
- 排列 && 组合
最近编程经常遇到需要 排列&&组合(求子集) 的问题:遂整理一下. 1. 数字的排列与组合(递归):O(n!),O(nC(n,k)) * O(n) #include <stdio ...
- DFS实现排列组合
所谓排列,是指从给定的元素序列中依次取出元素,需要考虑取出顺序.比如,取出元素3, 5,因取出顺序的不同,则形成的序列{3, 5}与{5, 3}是不同的排列序列.对于长度为n的元素序列取出k个元素,则 ...
- 面试题: 已知一个含有n个不同元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)
TX面试题2: 已知一个含有n个元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的) 题目分析, 为了便于说明,不妨将问题简化一下: 已知一个盒子中有n个不同的球,分别标记为{a1,a2,. ...
- dfs 全排列 使用交换——含重复元素和非重复元素
15. 全排列 中文 English 给定一个数字列表,返回其所有可能的排列. 样例 样例 1: 输入:[1] 输出: [ [1] ] 样例 2: 输入:[1,2,3] 输出: [ [1,2,3], ...
- PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?
首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...
- N个数组中所有元素的排列组合(笛卡尔积)算法
(1)N个数组对象中所有元素排列组合算法 private List<List<Object>> combineAlg(List<Object[]> nArray) ...
随机推荐
- 认识随机函数rand()和srand(unsigned int )
rand函数 int rand( void ); 函数名: rand 功 能: 随机数发生器 用 法: int rand(void); 所在头文件: stdlib.h 函数说明 : ...
- Arcmap图层浏览遇到ORA-07445 [QCDLAUCN] 错误
Oracle 12.1.0.2版本,在图层浏览时遇到了ORA-07445 [QCDLAUCN] 错误.根据MOS的查询结果,得知这是一个bug (Doc ID 1932725.1): 文章中同时给出了 ...
- ASP.NET-------gridview 进行编辑的时候,给出提示
在使用gridview 控件的时候,控制修改人的操作行为,并给出合理的提示, 比如 在执行编辑操作的时候 不允许姓名为空,并显示出提示,姓名不可以为空 操作: 前台页面,对一些字段的解释 一定要注意 ...
- unity文件路径
转载自:https://blog.csdn.net/linxinfa/article/details/51679528 各平台具体路径: 1.Resources Resources文件夹是一个只读的文 ...
- C语言 宏定义的1<<0 与 直接定义1 有什么区别
[1]示例程序 如下示例代码: #include <stdio.h> #define TEST1 1 << 0 #define TEST2 (1 << 0) #de ...
- day58——模板继承、组件、自定义标签和过滤器、inclusion_tag、静态文件配置、url别名和反向解析、url命名空间
day58 模板相关 模板继承(母版继承) 1. 创建一个xx.html页面(作为母版,其他页面来继承它使用) 2. 在母版中定义block块(可以定义多个,整个页面任意位置) {% block co ...
- Linux平台上常用到的c语言开发程序
Linux操作系统上大部分应用程序都是基于C语言开发的.小编将简单介绍Linux平台上常用的C语言开发程序. 一.C程序的结构1.函数 必须有一个且只能有一个主函数main(),主函数的名为main. ...
- golang --for语句
一条for 语句可以携带一条for子句. for子句可以包含初始化子句.条件子句.后置子句. package main import ( "fmt" ) func main() { ...
- String.Operation
// 字符串切割 StringField.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
- Mysql关键字Explain 性能优化神器
Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析查询语句或是结构的性能瓶颈.在select语句之前增加explaion关键字,MySQL会在查询上设置一个标记,执行查 ...