zoukankan      html  css  js  c++  java
  • 【LeetCode & 剑指offer刷题】回溯法与暴力枚举法题7:Subsets(系列)

    【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

    Subsets

    Given a set of distinct integers, nums, return all possible subsets (the power set).
    Note: The solution set must not contain duplicate subsets.
    Example:
    Input: nums = [1,2,3]
    Output:
    [
    [3],
    [1],
    [2],
    [1,2,3],
    [1,3],
    [2,3],
    [1,2],
    []
    ]

    C++
     
    //子集问题1:返回一个数组所有子集(不包含重复元素)
    /*
    方法一:递归
    每个元素,都有两种选择,选或不选
    增量构造法,深搜,时间复杂度O(2^n),空间复杂度O(n)
     
    需包含空集
    */
    /*
    class Solution
    {
    public:
        vector<vector<int>> subsets(vector<int>& nums)
        {
            vector<vector<int>> result;
            vector<int> path;
            if(nums.empty()) return result;
           
            sort(nums.begin(), nums.end()); //输出如果要求有序,需加上此句
            subsets(nums, path, 0, result);
            return result;
        }
    private:
        void subsets(vector<int>& nums, vector<int>& path, int step, vector<vector<int>>& result)
        {
            if(step == nums.size()) //到达树末尾时,push当前路径上元素都结果向量中
            {
                result.push_back(path);
                return;
            }
           
         //每一步两种选择,构成树的两个分支  
            //不选nums[step]
            subsets(nums, path, step+1, result);
            //选nums[step]
            path.push_back(nums[step]);
            subsets(nums, path, step+1, result);
            path.pop_back(); //释放空间,供下个分支存放元素
        }
    };*/
    /*
    方法二:迭代法
    增量构造法
    时间复杂度O(2^n),空间复杂度O(1)
    */
     
     
     
    90. Subsets II
    Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).
    Note: The solution set must not contain duplicate subsets.
    Example:
    Input: [1,2,2]
    Output:
    [
    [2],
    [1],
    [1,2,2],
    [2,2],
    [1,2],
    []
    ]

     
    //子集问题2:返回一个数组所有子集(可能包含重复元素)
    /*
    递归法:
    subsets I不同之处在与,每次dfspush结果,即每个分支就push该路径,而不是到末尾之后push
    例子:
    输入[1,2,2],递归树为
        - 1 - 2 -2
     []
        - 2 - 2
    故结果为[] 1 12 122
              2 22
    通过限制使每个父结点的子结点元素不相同,从而构造子集
    */
    /*
    方法二:也可以统计每个元素出现的次数,用类似排列2的做法,不过还没想明白
    */
    class Solution
    {
    public:
        vector<vector<int>> subsetsWithDup(vector<int>& nums)
        {
            vector<vector<int>> result;
            vector<int> path;
            if(nums.empty()) return result;
           
            sort(nums.begin(), nums.end()); //必须排序,这样重复的数才会相邻
            dfs(nums, 0, path, result);
            return result;
        }
    private:
        //start为每个父结点的子结点开始的数,子结点取nums[start~end],但不能取重复数
        void dfs(vector<int>& nums, int start, vector<int>& path, vector<vector<int>>& result)
        {
            result.push_back(path); //每个结点都push,包括根结点(对应空vector
           
            for(int i = start; i<nums.size(); i++) //产生某个父结点的多个子结点(子结点值不能相同),但父结点可以与子结点相同,if语句中的i!=start所起作用
            {
                if(i != start && nums[i] == nums[i-1]) continue; //如果同一个父结点的当前子结点值与上一个子结点相同,则不运行下面递归代码,进行分支开辟
                path.push_back(nums[i]);
                dfs(nums, i+1, path, result); //注意这里传递i+1,类似组合问题的递归法
                path.pop_back(); //给下个分支腾出空间
            }
        }
       
    };
     
     
  • 相关阅读:
    Partition4:增加分区
    Partition5:Partiton Scheme是否指定Next Used?
    UniqueIdentifier 数据类型 和 GUID 生成函数
    SQL Server 并发控制 第三篇:隔离级别和行版本(2)
    SQL Server 常用内置函数
    In-Memory:在内存中创建临时表和表变量
    Partition2:对现有表分区
    Partition1:新建分区表
    Partition3:分区切换(Switch)
    Pivot 和 Unpivot
  • 原文地址:https://www.cnblogs.com/wikiwen/p/10229470.html
Copyright © 2011-2022 走看看