目录
当前位置: 首页 > 文档资料 > LeetCode 题解 >

Backtracking - Subsets

优质
小牛编辑
135浏览
2023-12-01

Given a set of distinct integers, S, 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 S = [1,2,3], a solution is:

>

  1. [
  2. [3],
  3. [1],
  4. [2],
  5. [1,2,3],
  6. [1,3],
  7. [2,3],
  8. [1,2],
  9. []
  10. ]

>

这题其实就是列出集合里面的所有子集合,同时要求子集合元素需要升序排列。

首先我们需要对集合排序,对于一个n元素的集合,首先我们取第一个元素,加入子集合中,后面的n - 1个元素可以认为是第一个元素的子节点,我们依次遍历,譬如遍历到第二个元素的时候,后续的n - 2个元素又是第二个元素的子节点,再依次遍历处理,直到最后一个元素,然后回溯,继续处理。处理完第一个元素之后,我们按照同样的方式处理第二个元素。

譬如上面的[1, 2, 3],首先取出1,加入子集合,后面的2和3就是1的子节点,先取出2,把[1, 2]加入子集合,后面的3就是2的子节点,取出3,把[1, 2, 3]加入子集合。然后回溯,取出3,将[1, 3]加入子集合。

1处理完成之后,我们可以同样方式处理2,以及3。

代码如下:

  1. class Solution {
  2. public:
  3. vector<vector<int> > res;
  4. vector<vector<int> > subsets(vector<int> &S) {
  5. if(S.empty()) {
  6. return res;
  7. }
  8. sort(S.begin(), S.end());
  9. //别忘了空集合
  10. res.push_back(vector<int>());
  11. vector<int> v;
  12. generate(0, v, S);
  13. return res;
  14. }
  15. void generate(int start, vector<int>& v, vector<int> &S) {
  16. if(start == S.size()) {
  17. return;
  18. }
  19. for(int i = start; i < S.size(); i++) {
  20. v.push_back(S[i]);
  21. res.push_back(v);
  22. generate(i + 1, v, S);
  23. v.pop_back();
  24. }
  25. }
  26. };

Subsets II

Given a collection of integers that might contain duplicates, S, 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 S = [1,2,2], a solution is:

>

  1. [
  2. [2],
  3. [1],
  4. [1,2,2],
  5. [2,2],
  6. [1,2],
  7. []
  8. ]

>

这题跟上题唯一的区别在于有重复元素,但是我们得到的子集合又不能有相同的,其实做法很简单,仍然按照上面的处理,只是遍历子节点的时候如果发现有相等的,只遍历一个,后续跳过。代码如下:

  1. class Solution {
  2. public:
  3. vector<vector<int> > res;
  4. vector<vector<int> > subsetsWithDup(vector<int> &S) {
  5. if(S.empty()) {
  6. return res;
  7. }
  8. sort(S.begin(), S.end());
  9. res.push_back(vector<int>());
  10. vector<int> v;
  11. generate(0, v, S);
  12. return res;
  13. }
  14. void generate(int start, vector<int>& v, vector<int> &S) {
  15. if(start == S.size()) {
  16. return;
  17. }
  18. for(int i = start; i < S.size(); i++) {
  19. v.push_back(S[i]);
  20. res.push_back(v);
  21. generate(i + 1, v, S);
  22. v.pop_back();
  23. //这里跳过相同的
  24. while(i < S.size() - 1 && S[i] == S[i + 1]) {
  25. i++;
  26. }
  27. }
  28. }
  29. };