leetcode:78. 子集

题目

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例:

  1. 输入:nums = [1,2,3]
  2. 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
  1. 输入:nums = [0]
  2. 输出:[[],[0]]

解答 & 代码

递归回溯:
写法一

  1. class Solution {
  2. private:
  3. vector<vector<int>> resultList;
  4. vector<int> curSet; // 记录回溯算法当前走的路径
  5. // 回溯算法核心函数,遍历子集问题的回溯树
  6. // 当前是第 start 层,得到元素个数为 start 的子集
  7. void backtrack(vector<int>& nums, int start)
  8. {
  9. // 前序位置,每个节点的值都是一个子集
  10. resultList.push_back(curSet);
  11. // 回溯算法标准框架
  12. for(int i = start; i < nums.size(); ++i)
  13. {
  14. // 做选择
  15. curSet.push_back(nums[i]);
  16. // 递归回溯,通过 start 参数控制树枝的遍历,避免产生重复的子集
  17. backtrack(nums, i + 1);
  18. // 撤销选择
  19. curSet.pop_back();
  20. }
  21. }
  22. public:
  23. vector<vector<int>> subsets(vector<int>& nums) {
  24. backtrack(nums, 0);
  25. return resultList;
  26. }
  27. };

复杂度分析:设整数数组 nums 有 n 个元素

  • 时间复杂度[中等] 78. 子集 - 图1:n 个元素,每个元素都可以选择放到子集里 or 不放到子集里,一共 [中等] 78. 子集 - 图2个状态,每个状态需要 O(n) 的时间构造子集
  • 空间复杂度 O(n):递归栈空间 = 子集的最大长度

执行结果:

  1. 执行结果:通过
  2. 执行用时:0 ms, 在所有 C++ 提交中击败了 100.00% 的用户
  3. 内存消耗:7 MB, 在所有 C++ 提交中击败了 60.67% 的用户

写法二

  1. class Solution {
  2. private:
  3. vector<vector<int>> resultList;
  4. vector<int> curSet;
  5. void backtrack(vector<int>& nums, int start)
  6. {
  7. if(start == nums.size())
  8. {
  9. resultList.push_back(curSet);
  10. return;
  11. }
  12. curSet.push_back(nums[start]);
  13. backtrack(nums, start + 1);
  14. curSet.pop_back();
  15. backtrack(nums, start + 1);
  16. }
  17. public:
  18. vector<vector<int>> subsets(vector<int>& nums) {
  19. backtrack(nums, 0);
  20. return resultList;
  21. }
  22. };

执行结果:

  1. 执行结果:通过
  2. 执行用时:4 ms, 在所有 C++ 提交中击败了 43.03% 的用户
  3. 内存消耗:6.8 MB, 在所有 C++ 提交中击败了 90.46% 的用户