LintCode笔记(11)—— 带重复元素的子集
2017-01-20 10:00
393 查看
给定一个可能具有重复数字的列表,返回其所有可能的子集
注意事项
子集中的每个元素都是非降序的
两个子集间的顺序是无关紧要的
解集中不能包含重复子集
您在真实的面试中是否遇到过这个题?
Yes
样例
如果 S =
与这道题相类似的题目同样也是求子集,不过限定集合中不包含重复的元素,但是这道题目不限定集合中是否有重复元素,因此这道题的答案同样可以应用到限制不包含重复元素的题目。对于这类题目,我只想到了一种使用非递归的解决方法。
首先我们知道有n个元素的集合,则它一共有2^n个子集(包括空集和它自身),那么对于有n个字符的集合,我们可以使用n位的二进制数标志该n个元素集合的哪些元素在它的子集中。
例如有3个元素的集合{1,2,3},一共有8个子集,则用3位的二进制数标志为:
00,001,010,011,100,101,110,111,其中若某位为1,则标志该位的元素在该子集中,则这8个二进制数对应的子集分别为 {},{3},{2},{2,3},{1},{1,3},{1,2},{1,2,3}。
而对于本题中的集合可能存在相同的元素的要求,我们可以在插入新得到的子集到结果集之前首先判断结果集中是否已经存在与该子集相等的子集,若存在则不插入,若不存在则直接插入。
实现代码如下:
注意事项
子集中的每个元素都是非降序的
两个子集间的顺序是无关紧要的
解集中不能包含重复子集
您在真实的面试中是否遇到过这个题?
Yes
样例
如果 S =
[1,2,2],一个可能的答案为:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
与这道题相类似的题目同样也是求子集,不过限定集合中不包含重复的元素,但是这道题目不限定集合中是否有重复元素,因此这道题的答案同样可以应用到限制不包含重复元素的题目。对于这类题目,我只想到了一种使用非递归的解决方法。
首先我们知道有n个元素的集合,则它一共有2^n个子集(包括空集和它自身),那么对于有n个字符的集合,我们可以使用n位的二进制数标志该n个元素集合的哪些元素在它的子集中。
例如有3个元素的集合{1,2,3},一共有8个子集,则用3位的二进制数标志为:
00,001,010,011,100,101,110,111,其中若某位为1,则标志该位的元素在该子集中,则这8个二进制数对应的子集分别为 {},{3},{2},{2,3},{1},{1,3},{1,2},{1,2,3}。
而对于本题中的集合可能存在相同的元素的要求,我们可以在插入新得到的子集到结果集之前首先判断结果集中是否已经存在与该子集相等的子集,若存在则不插入,若不存在则直接插入。
实现代码如下:
#include <iostream> #include <vector> #include <math.h> #include <algorithm> using namespace std; static bool sortByNum(int num1, int num2) { return num1 < num2; } //把指定的int类型的数字转换为二进制字符串,存入binaryStr中 //binaryStr为已经定长的vector数组,初始化全部元素为0 void intToBinary(int num, vector<int>& binaryStr) { int i = 0; while (num / 2 != 0) { binaryStr[binaryStr.size() - i - 1] = num % 2; num = num / 2; i++; } binaryStr[binaryStr.size() - i - 1] = num % 2; } /** * @param S: A set of numbers. * @return: A list of lists. All valid subsets. */ vector<vector<int> > subsets(vector<int> &nums) { // write your code here vector<vector<int> > result; //一共有2^(nums.size())个子集 for (int i = 0; i < pow(2,nums.size()); i++) { //二进制字符串数组,某元素为1表示该元素在该子集元素中 vector<int> flags; //初始化 for (int m = 0; m < nums.size(); m++) flags.push_back(0); intToBinary(i, flags); vector<int> tmp; for (int j = 0; j < flags.size(); j++) { if (flags[j] == 1) { tmp.push_back(nums[j]); } } sort(tmp.begin(), tmp.end(), sortByNum); //针对有可能有重复元素的集合,加入到result集之前首先判断是否已经有与待加入元素相同的元素 bool exists = false; for (size_t m = 0; m < result.size(); m++) { if (tmp == result[m]) exists = true; } if (exists == false) result.push_back(tmp); } return result; } int main() { vector<int> test; test.push_back(1); test.push_back(2); test.push_back(2); vector<vector<int> > result = subsets(test); cout << result.size() << endl; for (int i = 0; i < result.size(); i++) { for (int j = 0; j < result[i].size(); j++) { cout << result[i][j] << " # "; } cout << endl; } return 0; }
相关文章推荐
- LintCode 18 带重复元素的子集
- lintcode 中等题:subsets II 带重复元素的子集
- LintCode 18-带重复元素的子集 JAVA
- (lintcode)第18题 带重复元素的子集
- lintcode-18-带重复元素的子集
- LintCode 18. 带重复元素的子集
- lintcode---子集(带重复元素和不带重复元素的两种解法)
- lintcode-带重复元素的子集-18
- ***[Lintcode]Permutations II 带重复元素的排列 递归/非递归解法
- lintcode 容易题:Remove Duplicates from Sorted List 删除排序链表中的重复元素
- [LintCode] 带重复元素的排列
- 【计蒜客系列】挑战难题11:移除数组中重复元素
- 左程云著算法与数据结构题目最优解笔记-删除无序链表中重复的元素
- Java基础知识强化之集合框架笔记28:ArrayList集合练习之去除ArrayList集合中的重复字符串元素(升级)
- [LeetCode系列]子集枚举问题[无重复元素]
- LintCode(easy)删除排序数组中重复元素
- 子集生成之增量构造法(允许有重复元素)
- 集合的子集生成(无重复元素)
- 面试题: 已知一个含有n个不同元素的集合,要求打印其所有具有k个元素的子集(不允许有重复的)
- lintcode-带重复元素的排列 -16