力扣 leetcode 78. 子集

问题描述

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

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

提示:

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

示例

示例 1:

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

示例 2:

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

解题思路

这里考察的是递归的基本用法,我们要注意保存上一次递归时的状态,以及考虑递归终止条件。

这里保存上一次递归时的状态有两个作用,一是为了记录结果;二是为了避免重复添加。

递归的终止条件可以根据子数组的长度来决定。

class Solution {
public:
    // 递归求解
    void pushItem(vector<vector<int>>& res, vector<int>& nums, vector<bool>& visited, int idx, int step){
        if(step){ // step控制此时子数组的长度
            step--;
            // i 从idx开始,可以避免重复
            for(int i = idx; i < nums.size() - step; i++){
                if(!visited[i]){
                    visited[i] = true;
                    // 注意,此时下一次for循环的i从 i + 1开始,避免出现[nums[0], nums[1]],[nums[1], nums[0]]的情况
                    pushItem(res, nums, visited, i + 1, step);
                    visited[i] = false;
                }
            }
        }
        else{
            vector<int> r;
            for(int i = 0; i < nums.size(); i++){
                if(visited[i]){
                    r.push_back(nums[i]);
                }
            }
            // 添加结果
            res.push_back(r);
        }
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        const int n = nums.size();
        if(!n){
            return {nums};
        }
        // 结果中至少有一个{}
        vector<vector<int>> res(1, vector<int> {});
        vector<bool> visited(n, false);
        int idx = 0;
        // 这里将长度为1到n的子数组都添加
        for(int i = 1; i <= n; i++){
            pushItem(res, nums, visited, idx, i);
        }
        return res;
    }
};
posted @ 2022-12-07 22:21  greatestchen  阅读(15)  评论(0编辑  收藏  举报