题目链接

LeetCode

题目描述

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

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

示例 2:

输入: nums = [0]
输出: [[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

    解题思路

    方法一:迭代法实现子集枚举

    image.png

    1. class Solution {
    2. public:
    3. vector<int> t;
    4. vector<vector<int>> ans;
    5. vector<vector<int>> subsets(vector<int>& nums) {
    6. int n = nums.size();
    7. // 1<<n 表示 2^n
    8. for (int mask = 0; mask < (1 << n); ++mask) {
    9. t.clear();
    10. // 遍历每一位为 1 的下标
    11. for (int i = 0; i < n; ++i) {
    12. // 与运算 mask第i位为 1 则为true
    13. if (mask & (1 << i)) {
    14. t.push_back(nums[i]);
    15. }
    16. }
    17. ans.push_back(t);
    18. }
    19. return ans;
    20. }
    21. };
  • 时间复杂度 O(n * 2^n)

  • 空间复杂度 O(n)

    方法二:递归回溯法

    假设我们需要找到一个长度为 n 的序列 a 的所有子序列,代码框架是这样的:

    1. vector<int> t;
    2. void dfs(int cur, int n) {
    3. if (cur == n) {
    4. // 记录答案
    5. // ...
    6. return;
    7. }
    8. // 考虑选择当前位置
    9. t.push_back(cur);
    10. dfs(cur + 1, n, k);
    11. t.pop_back();
    12. // 考虑不选择当前位置
    13. dfs(cur + 1, n, k);
    14. }

    image.png

    1. class Solution {
    2. public:
    3. vector<int> t;
    4. vector<vector<int>> ans;
    5. void dfs(int cur, vector<int>& nums) {
    6. if (cur == nums.size()) {
    7. // 记录答案
    8. ans.push_back(t);
    9. return;
    10. }
    11. // 考虑选择当前位置
    12. t.push_back(nums[cur]);
    13. dfs(cur + 1, nums);
    14. // 考虑不选择当前位置
    15. t.pop_back();
    16. dfs(cur + 1, nums);
    17. }
    18. vector<vector<int>> subsets(vector<int>& nums) {
    19. dfs(0, nums);
    20. return ans;
    21. }
    22. };
    1. class Solution {
    2. private List<List<Integer>> res = new ArrayList<List<Integer>>();
    3. private List<Integer> path = new ArrayList<Integer>();
    4. public List<List<Integer>> subsets(int[] nums) {
    5. dfs(nums,0);
    6. return res;
    7. }
    8. private void dfs(int[] nums,int cur){
    9. if(cur == nums.length){
    10. res.add(new ArrayList<Integer>(path));
    11. return;
    12. }
    13. path.add(nums[cur]);
    14. dfs(nums,cur+1);
    15. path.remove(path.size()-1);
    16. dfs(nums,cur+1);
    17. }
    18. }
  • 时间复杂度 O(n * 2^n)

  • 空间复杂度 O(n)