LeetCode 78.子集(回溯)

122 阅读1分钟

从零开始学习c++,每天起码做一道leetcode题目,在此记录,希望最后能够有所收获!

一、题目描述

78.子集

给你一个整数数组 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 中的所有元素 互不相同

二、思路分析

这题大体的套路和之前类似,基本的解题流程是类似的。但通过画树状图就会发现,收获结果的地方不一样了。在前面的组合和分割字符串中,收获结果的地方都是在最后的叶子结点。但在本题中,通过画树状图就可以知道,收获结果的地方是在子节点中,也就是每一个节点都有我们所需要的结果。

在我自己写的代码中,将收获结果也就是ans.push_back(path);这一行代码放在了for循环下面。但这样会导致结果漏掉了一个空集,所以我又在后面把空集单独添加上去了。

其实最正确的这行代码应该放在backtracking这个函数的起始位置。每一个递归到这个函数,也就是又来到了一个节点,需要将path加入到ans中。

最后返回结果即可。

三、AC代码

class Solution {
public:
    vector<vector<int>>ans;
    vector<int>path;
    void backtracking(vector<int>& nums,int n,int startindex){
        if(startindex>=n){
            return;
        }
        for(int i=startindex;i<n;i++){
            path.push_back(nums[i]);
            ans.push_back(path);
            backtracking(nums,n,i+1);
            path.pop_back();
        }
    }  
    vector<vector<int>> subsets(vector<int>& nums) {
        int n=nums.size();
        vector<int>x={};
        backtracking(nums,n,0);
        ans.push_back(x);
        return ans;

    }
};

四、总结

在画出了树状分析图后,就有一定的解题思路了,仔细梳理的话不算太难,关键是要知道与之前题目有哪里是不同的。