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]