Subsets & Subsets II
78. Subsets
题目链接:https://leetcode.com/problems/subsets/#/description
题目大意:给定一个整数集合,所有的整数都不相等,要求返回所有可能的子集。
题目思路:排列组合问题,集合中的任意元素,都能产生两类子集,一类包含该元素,一类不包含该元素。
算法步骤:(1)将子集集合初始化为只包含一个空集,并从集合中取出第一个元素作为当前元素;(2)保留原有的子集,再对原有子集集合中的每一个元素添加当前元素后获得一个新的子集,并将获得的子集添加到子集集合中。(3)如果集合中仍有元素,则选取下一个元素作为当前元素,并调到(2),否则返回所有子集的集合。
算法复杂度:时间复杂度O(2^n),空间复杂度O(n*2^n)
代码:
1 class Solution { 2 public: 3 vector<vector<int>> subsets(vector<int>& nums) { 4 vector<vector<int>> subsets(1); 5 for (int i = 0; i < nums.size(); ++i) { 6 int n = subsets.size(); 7 for (int j = 0; j < n; ++j) { 8 subsets.push_back(subsets[j]); 9 subsets.back().push_back(nums[i]); 10 } 11 } 12 return subsets; 13 } 14 };
评测系统上运行结果:
90. Subsets II
题目链接:https://leetcode.com/problems/subsets-ii/#/description
题目大意:给定一个整数集合,整数可能重复,要求返回所有可能的子集
思路:排列组合问题,对于集合中的任意元素,若该元素唯一,则能产生两类子集,一类包含该元素,一类不包含该元素,若该元素不唯一,假设有n个,这n个元素能产生n+1类圈子,分别是不包含该元素,包含1个,2个,...,n个该元素。
算法步骤:(1)将集合元素排序,子集集合初始化为只包含一个空集,并从集合中取出第一个元素作为当前元素,当前元素加1作为前一个元素,并将需要新增子集数n初始化为1;(2)保留原有的子集,再对原有子集集合中的最后n个元素添加当前元素后获得一个新的子集,并将获得的子集添加到子集集合中。将当前元素赋值给前一个元素(3)如果集合中仍有元素,则选取下一个元素作为当前元素,如果当前元素与前一个元素不等,则n更新为当前子集的个数,然后调到(2),如果集合中已经没有元素,则返回所有子集的集合。
算法复杂度:时间复杂度O(2^n),空间复杂度O(n*2^n),n为集合中不同元素的个数。
代码:
1 class Solution { 2 public: 3 vector<vector<int>> subsetsWithDup(vector<int>& nums) { 4 vector<vector<int>> res(1); 5 if (nums.empty()) 6 return res; 7 sort(nums.begin(), nums.end()); 8 int pre = nums[0] + 1; 9 int n = 1; 10 for (int i = 0; i < nums.size(); ++i) { 11 if (pre != nums[i]) 12 n = res.size(); 13 int end = res.size(); 14 for (int j = res.size() - n; j < end; ++j) { 15 res.push_back(res[j]); 16 res.back().push_back(nums[i]); 17 } 18 pre = nums[i]; 19 } 20 return res; 21 } 22 };
评测系统上运行结果: