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) ...
随机推荐
- 【神经网络与深度学习】neural-style、chainer-fast-neuralstyle图像风格转换使用
neural-style 官方地址:这个是使用torch7实现的;torch7安装比较麻烦.我这里使用的是大神使用TensorFlow实现的https://github.com/anishathaly ...
- 小米win10+kali 双系统
1.下载kali linux 系统镜像,用windisk32imager 制作启动盘,制作好后千万不要格式化u盘,其他的启动盘制作工具不好用,无法加载系统镜像 2.将u盘插入电脑,重启,电脑重启时按 ...
- Debug 路漫漫-08:Keras 版本升级函数变换导致的问题
在使用 CNN的时候,报错: TypeError: ('Keyword argument not understood:', 'padding') 将“padding”改为“border_mode”, ...
- SpringBoot系列教程web篇Servlet 注册的四种姿势
原文: 191122-SpringBoot系列教程web篇Servlet 注册的四种姿势 前面介绍了 java web 三要素中 filter 的使用指南与常见的易错事项,接下来我们来看一下 Serv ...
- centos 7 重新设置分区大小
一.基础概念Cent0S 7默认启用LVM2(Logical Volume Manager),把机器的一块硬盘分为两个区sda1和sda2,其中分区sda1作为系统盘/boot挂载,少量空间:sda2 ...
- windows版mysql安装
https://blog.csdn.net/ycxzuoxin/article/details/80908447
- vue的package.json文件理解
参考文档: https://www.cnblogs.com/tzyy/p/5193811.html#_h1_0 https://www.cnblogs.com/hongdiandian/p/83210 ...
- Hive sampling 语法之TABLESAMPLE用法理解
官网关于LanguageManual Sampling的教程,部分截图如下,这里主要分享对TABLESAMPLE(BUCKET 3 OUT OF 16 ON id)子句的理解 官网中假设创建表时设 ...
- shell-快速入门_批处理脚本编程语言
1. Shell概述 1.1. Shell是什么 Shell是一门批处理脚本编程语言. 批处理是什么? 操作系统都分为(GUI)图形界面,命令界面(command). 命令操作的可以不用一一条执行.可 ...
- 基于OpenGL的三维曲面动态显示实现
在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成. 1.基于OpenGL绘图的基本设置 1.1 设 ...