leetcode 78. Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

题目大意:给定一个数组(数字不重复),返回它的全集。

 

思路一:回溯法,从第一个开始。

 1 class Solution {
 2 public:
 3     vector<vector<int>> subsets(vector<int>& nums) {
 4         int len = nums.size();
 5         vector<int> v;
 6         vector<vector<int> > res;
 7         subsets(0, len, nums, v, res);
 8         return res;
 9     }
10 private:
11     void subsets(int i, int len, vector<int> nums, vector<int> &v, vector<vector<int> > &res) {
12         res.push_back(v);
13         for (int j = i; j < len; j++) {
14             v.push_back(nums[j]);
15             subsets(j + 1, len, nums, v, res);
16             v.pop_back();
17         }
18     }
19 };

 添加过程:

[ ]

[1]

[1, 2]

[1, 2, 3]

[1, 3]

[2]

[2, 3]

[3]

思路二:

一开始,我们只有空集一个子集。

[ ],

当遇到第0个元素1, 我们可以将元素1放进全集中已有的子集,也可以不放,有两种选择。产生:[ ], [1].

当遇到第1个元素2, 我们可以将元素2放进全集中已有的子集,也可以不放,有两种选择。产生:[ ], [1], [2], [1,2]

当遇到第2个元素3, 我们可以将元素3放进全集中已有的子集,也可以不放,有两种选择。产生:[ ], [1], [2], [1,2], [3], [1,3], [2,3], [1,2,3].

 1 class Solution {
 2 public:
 3     vector<vector<int>> subsets(vector<int>& nums) {
 4         int len = nums.size();
 5         vector<vector<int> > res(1);
 6         for (int i = 0; i < len; i++) { 
 7             int l = res.size(); // get the size of current power set
 8             for (int j = 0; j < l; j++) {
 9                 res.push_back(res[j]);
10                 res.back().push_back(nums[i]);
11             }
12         }
13         return res;
14     }
15 };

 添加过程:

[ ]

[1]

[2]

[1, 2]

[3]

[1,3]

[2,3]

[1,2,3]

 

思路三:位操作

其实生成子集的思想在于包括包括某一个元素,即每一个元素就两种状态,选与不选,比如,每个元素都不选,就是空集,每个元素都选,就是集合本身。假如集合的势为n, 那么全集的元素个数有2n

针对这题的例子:

[1,2,3],

我们求全集(共有8个元素)

全集的第0(二进制表示:000)个元素:空集,即每个元素都不选。

全集的第1(二进制表示:001)个元素:[3],即只选第2个元素。

全集的第2(二进制表示:010)个元素:[2],即只选第1个元素。

全集的第3(二进制表示:100)个元素:[1],即只选第0个元素。

......

全集的第7(二进制表示:111)个元素:[3,2,1],即每个元素都选。

 1 class Solution {
 2 public:
 3     vector<vector<int>> subsets(vector<int>& nums) {
 4         int len = nums.size();
 5         int size = 1 << len;
 6         vector<vector<int> > res(size);
 7         for (int i = 0; i < size; i++) {
 8             for (int j = 0; j < len; j++) {
 9                 if ((i >> j) & 1)
10                     res[i].push_back(nums[j]);
11             }
12         }
13         return res;
14     }
15 };

 添加过程:

[]

[3]

[2]

[3, 2]

[1]

[3, 1]

[2, 1]

[3, 2, 1]

posted @ 2019-09-05 15:06  琴影  阅读(200)  评论(0编辑  收藏  举报