78. Subsets(中等,集合的子集,经典问题 DFS)
Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
就是求指定集合的所有子集.
三种解法:
- Recursive (Backtracking) 道理能理解,代码不容易写;
- Iterative 本文用的解法,好直接,易理解和实现;
- Bit Manipulation 还没学,再补充.
方法1, Recursive (Backtracking)
代码中的注释是我的理解.
// Recursive (Backtracking)
vector<vector<int>> subsets(vector<int>& A) {
sort(A.begin(), A.end()); // sort
vector < vector<int> > res;
vector<int> sub;
// 四个参数
// A, 二维res, 临时sub, 待处理数组A元素索引号indx
genSubset(A, res, sub, 0);
return res;
}
// DFS:
// box 套 box, 好奇的小儿一直往里面开 box
void genSubset(vector<int>& A, vector<vector<int> >& res, vector<int> sub,
int start) {
res.push_back(sub);
for (int i = start; i < A.size(); i++) {
// 假设 sub = [1]
// sub里压入一个2, sub = [1, 2]
sub.push_back(A[i]);
// 看看压入2后, 还有谁?!!
genSubset(A, res, sub, i + 1);
// 还有谁的事,由genSubset探查完后,
// 把2弹出去, sub = [1], 然后下轮循环, 看看谁还能和 1 搭个伴,
// 假设A中还有3, 那么下次循环 sub = [1, 3]
// 直到 1 和所有A中剩余元素都结合过
sub.pop_back();
}
}
方法2, Iterative
想法:
就是编程实现下面的东西:
[[]]
[[], []] --> [[], [1]]
[[],[1]] -复制-> [[],[1],[],[1]] -添值-> [[],[1],[2],[1, 2]]
[[],[1],[2],[1, 2]] -复制-> [[],[1],[2],[1, 2],[],[1],[2],[1, 2]] -添值-> [[],[1],[2],[1, 2],[3],[1,3],[2,3],[1, 2, 3]]
上面的例子不太准确(细节写准确太长了,下面针对一个小东西仔细描述过程),但思路是对的.
下面才是程序真正的执行结果:
应该是这样的,我们拿出一小段做解释^^
[[],[1]] -复制-> [[],[1],[]] -添值-> [[],[1],[2]] -复制-> [[],[1],[2],[1]] -添值-> [[],[1],[2],[1,2]]
人家想法,自己代码:
\(O(n^2)\) time, \(O(1)\) extra space.
vector<vector<int>> subsets(vector<int>& A) {
sort(A.begin(), A.end()); // sort
vector < vector<int> > res(1, vector<int>()); // declare res = [[],];
const int n = A.size();
for (int i = 0; i < n; i++) {
const int m = res.size();
for (int j = 0; j < m; j++) {
// 有坑, 注意, 不可妄图写成下面这样:
// res.push_back(res[j].push_back(A[i]));
res.push_back(res[j]); // [[], []]
res.back().push_back(A[i]); // [[], [1]]
}
}
return res;
}
顺便上面代码展示了一些关于c++写代码的副产品,如下:
- 声明一个
[[],]的二维数组:vector < vector<int> > res(1, vector<int>()); - 这么写结果不对:
for(auto it : res) res.push_back(it.push_back(A[i]));我晕! - 不能妄图写成这样:
res.push_back(res[j].push_back(A[i]));有点边迭代,边修改数组的意思. - push_back() 和 back() 的区别:
- coll.push_back()是把一个元素,放入这个容器的末尾,相当于末尾添加一个元素;
- coll.back()是获取最后一个元素的迭代器,你可以理解为最后一个元素的指针.
接下来是第3种方法,Bit Manipulation 但还没学,再补充.
TODO Bit Manipulation
78. Subsets(中等,集合的子集,经典问题 DFS)的更多相关文章
- [LeetCode] 78. Subsets 子集合
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
- [LeetCode] Subsets 子集合
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
- LeetCode OJ 78. Subsets
Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a subset must ...
- 刷题78. Subsets
一.题目说明 题目78. Subsets,给一列整数,求所有可能的子集.题目难度是Medium! 二.我的解答 这个题目,前面做过一个类似的,相当于求闭包: 刷题22. Generate Parent ...
- python 实现求一个集合的子集
概要 今天偶然看到有个关于数学中集合的问题,就突发奇想的想用python实现下求一个集合的子集. 准备 我当然先要复习下,什么是集合,什么是子集? 比较粗犷的讲法,集合就是一堆确定的东西,细致一点的讲 ...
- 78. Subsets(M) & 90. Subsets II(M) & 131. Palindrome Partitioning
78. Subsets Given a set of distinct integers, nums, return all possible subsets. Note: The solution ...
- leetcode 78. Subsets 、90. Subsets II
第一题是输入数组的数值不相同,第二题是输入数组的数值有相同的值,第二题在第一题的基础上需要过滤掉那些相同的数值. level代表的是需要进行选择的数值的位置. 78. Subsets 错误解法: cl ...
- [python语法]python中如何判断一个集合是另一个集合的子集?
问:python中如何判断一个集合是另一个集合的子集? 答:用issubset()方法 语法: A.issubset(B) 返回: True 如果A是B的子集. False 如果A不是B的子集. 样例 ...
- 59-python基础-python3-集合-集合常用方法-判断一个集合是否是另一个集合的子集-issubset()-issuperset()
判断一个集合是否是另一个集合的子集-issubset()-issuperset() 1-issubset() s1.issubset(s) 判断s1是否是s的子集 2-issuperset() 与is ...
随机推荐
- 新概念英语(1-119)who call out to the thieves in the dark?
who call out to the thieves in the dark? A true story Do you like stories? I want to tell you a true ...
- leetcode算法: Find the Difference
Given two strings s and t which consist of only lowercase letters.String t is generated by random sh ...
- python多进程--------linux系统中python的os.fork()方法
linux下python 创建子进程的原理: os.fork()方法 的原理 为了实现并发.多任务,我们可以在主程序种开启一个进程或者线程.在类unix操作系统当中(非windows),可以用pyth ...
- zoj 3950 how many nines
https://vjudge.net/problem/ZOJ-3950 题意: 给出两个日期,计算从第一个日期开始到第二个日期,每一天的日期中的9加起来一共有多少个. 思路: 看题解补的题.首先看这题 ...
- SQL外连接
1.左外连接 取出左侧关系中所有与右侧关系中任一元组都不匹配的元组,用空值null充填所有来自右侧关系的属性,构成新的元组,将其加入自然连接的结果中 2.右外连接 取出右侧关系中所有与左侧关系中任一元 ...
- 在服务器上,配置redis可以外网访问
首先linux开放默认端口6379打开redis配置文件redis-conf注释掉 bind 127.0.0.1(默认只有本地主要才能访问)这个注释掉现在处于受保护的状态,外网连不上,因为没有密码 在 ...
- vue基础特性
在这里我们主要是讲解一些vue实例的属性和一些基础的指令 vue实例属性: 其实和我们之前所学的对象的属性是相似的东西 vue的基础指令: 对于指令,大家可能之前么有接触过相关的概念,其实大家可以这样 ...
- 列表(list)之一定义 添加 删除 排序 反转 索引等其他操作
1.定义: 创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可,序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. # 列表list1=[&q ...
- JavaScript高级程序设计(第3版)
准备开始分享阅读笔记 自己收获的同时 让更多的人收益 这也是我力荐的学习javascript基础的书籍
- JS日期格式化转换方法
1. 将日期转换为指定的格式:比如转换成 年月日时分秒 这种格式:yyyy-MM-dd hh:mm:ss 或者 yyyy-MM-dd.当然是网上的方法,只是总结下. Date.prototype.fo ...