码迷,mamicode.com
首页 > 编程语言 > 详细

[LeetCode] Subsets I (78) & II (90) 解题思路,即全组合算法

时间:2015-12-27 14:42:21      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

78. Subsets

Given a set of distinct integers, nums, return all possible subsets.

Note:

  • Elements in a subset must be in non-descending order.
  • 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],
  []
]

问题: 给定一个集合,求集合元素的所有组合的情况。

实际上就是一题求全组合的题目。

nums[i...n) 的所有组合情况可以分为两种:包含nums[i] 的 和 不包含 nums[i] 的。

  • 包含 nums[i] 的:nums[i] 依次加到 nums[i+1...n) 的全部情况即可。
  • 不包含 nums[i] 的 :就是 nums[i+1...n) 的全部情况。

上面的递推关系,实际上就是 DP 思路。

技术分享
 1     vector<vector<int>> theset;
 2     
 3     void regardValue(int value){
 4         
 5         if (theset.size() == 0) {
 6             vector<int> tmp0;
 7             vector<int> tmp1 = {value};
 8             theset.push_back(tmp0);
 9             theset.push_back(tmp1);
10             return;
11         }
12     
13         int LofPre = (int)theset.size();
14         
15         for (int i = 0 ; i < LofPre; i++) {
16             vector<int> tmp = theset[i];
17             tmp.push_back(value);
18             theset.push_back(tmp);
19         }
20     }
21 
22     vector<vector<int>> subsets(vector<int>& nums) {
23         
24         std::sort(nums.begin(), nums.end());
25         
26         for (int i = 0; i < nums.size(); i++) {
27             regardValue(nums[i]);
28         }
29         
30         return theset;
31     }
View Code

 

90. Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets.

Note:

  • Elements in a subset must be in non-descending order.
  • The solution set must not contain duplicate subsets.

 

For example,
If nums = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

问题:若集合中包含重复值,求所有的可能组合,即子集合。

要求:子集合内可以有重复值,但是子集合之间不可以有重复的子集合。

同样采用原来的思路,用 unordered_set<vector<int>> 代替 vector<vector<int>> ,就得最后结果后,再转为 vector<vector<int>> 即可。

在实现过程中发现 unordered_set<vector<int>> 不能直接使用。在 stackoverflow 看到解法方法,增加对 vector<int> 结构进行 hash 即可使用。修改后,算法实现并通过。

技术分享
 1     struct VectorHash {
 2         size_t operator()(const vector<int>& v) const {
 3             hash<int> hasher;
 4             size_t seed = 0;
 5             for (int i : v) {
 6                 seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
 7             }
 8             return seed;
 9         }
10     };
11     
12 
13     vector<vector<int>> theset;
14     
15     unordered_set<vector<int>, VectorHash> uniSet;
16 
17     void regardValue(int value){
18     
19         if (uniSet.size() == 0) {
20             vector<int> tmp0;
21             vector<int> tmp1 = {value};
22             uniSet.insert(tmp0);
23             uniSet.insert(tmp1);
24             return;
25         }
26         
27         unordered_set<vector<int>, VectorHash> cpSet = uniSet;
28     
29         unordered_set<vector<int>, VectorHash>::iterator t_iter;
30         
31         for (t_iter = cpSet.begin(); t_iter != cpSet.end(); t_iter++) {
32             vector<int> tmp = *t_iter;
33             
34             tmp.push_back(value);
35             uniSet.insert(tmp);
36         }
37     }
38 
39 
40 
41     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
42      
43          sort(nums.begin(), nums.end());
44     
45         for (int i = 0; i < nums.size(); i++) {
46             regardValue(nums[i]);
47         }
48                 
49         unordered_set<vector<int>, VectorHash>::iterator t_iter;
50         
51         for (t_iter = uniSet.begin(); t_iter != uniSet.end(); t_iter++) {
52             vector<int> tmp = *t_iter;
53             theset.push_back(tmp);
54         }
55         
56         return theset;
57         
58     }
View Code

 

[LeetCode] Subsets I (78) & II (90) 解题思路,即全组合算法

标签:

原文地址:http://www.cnblogs.com/TonyYPZhang/p/5079971.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!