• 78:子集(C++)


    题目地址:https://leetcode-cn.com/problems/subsets/

    题目描述

    给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    说明:解集不能包含重复的子集。

    题目示例

    示例:

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

    解题思路

    思路1:动态规划。我们使用二维数组进行存储,首先存储数组nums中的每个元素自身,然后以该元素为起点,分别遍历查找nums数组其它元素,最后将其加入到结果集中。以[1,2,3]为例,首先往res中添加空集,即[]。然后当循环第一次的时候,二维数组为空,此时,往结果集res中存放元素[1],即nums[0],现在res中相当于有了两个子集,即[],[1];循环第二次的时候,即要将nums[1]存放到前面的所有子集中,可以发现,res[0]是为空的,所以将nums[1]加入到res[0]的集合中,即[2]等价于[[],[2]];而res[1]是存在元素的,值为1,此时需要将nums[1]=2加入到res[1]集合中,从而构成子集[1,2];到次为止,res中拥有的子集为[],[1],[2],[1,2];接下来就是将nums[2]存放到所有的子集中,类似于上述流程,构成子集[3],[1,3],[2,3],[1,2,3];到目前为止,res中的子集全部结束,结果为[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]。

    思路2:递归求解。我们可以发现,当数组nums的元素为n时,其子集的数目为2^n个,而每个子集可以看作是对数组nums中的每个元素是否添加的过程,即选不选的问题,如果选,则把它加入进来,然后将所维护的数组元素减少一个;如果不选,则维护的数组不变。

    程序源码

    思路1

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> res;
            if(nums.empty()) return res;
            res.push_back({});
            // 当前加入的元素值为nums[i]
            for(int i= 0; i < nums.size(); i++)
            {
                int len = res.size(); // 前面i-1个子集中的元素个数
                // 将nums[i]分别放入res[j]的各个vect中,再放进res中
                for(int j = 0; j < len; ++j)
                {
                    // 将nums[i]放入空集中
                    if(res[j].empty()) res.push_back({nums[i]});
                    else{
                        vector<int> temp;
                        temp = res[j];
                        temp.push_back(nums[i]);
                        res.push_back(temp);
                    }
                }
            }
    
            return res;
        }
    };

    思路2

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> res; //结果集
            vector<int> list; //维护nums数组元素
            if(nums.empty()) return res;
            dfs(res, nums, list, 0);
            return res;
        }
        void dfs(vector<vector<int>>& res, vector<int>& nums, vector<int>& list, int index)
        {
            //递归终止条件
            if(index == nums.size())
            {
                res.push_back(list);
                return;
            }
            //递归求解,即处理当前层
            dfs(res, nums, list, index + 1); //不选该数,使得list不变
    
            list.push_back(nums[index]);
            dfs(res, nums, list, index + 1); //选择该数
            //清扫当前层的状态
            list.pop_back();
        }
    };
    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    netty编译报错
    idea快捷键:查找类中所有方法的快捷键
    vue修改浏览器的标题title
    django使用原生SQL的方法
    js 动态刷新页面日期
    H.264中的SPS和PPS
    CppProperties.json 参考
    FFmpeg代码导读——HEVC在RTMP中的扩展
    FFmpeg从入门到精通:SEI那些事
    FFmpeg代码导读——基础篇
  • 原文地址:https://www.cnblogs.com/wzw0625/p/13543552.html
Copyright © 2020-2023  润新知