• LeetCode78. 子集


    方法一(DFS回溯)

    求出所有可能的子集,就是要遍历一遍DFS递归树,把所有子集全都压入结果数组中。

    class Solution {
    vector<vector<int>> res;
    vector<int> onePath;                  //onePath是递归树的一条路径(一个子集)
    public:      
        vector<vector<int>> subsets(vector<int>& nums) {
            DFS(nums, 0);
            return res;
        }
        void DFS(vector<int>& nums, int depth) {            //depth是当前递归的深度
            res.push_back(onePath);                         //要求所有子集,所以把onePath压入res先
            for(int i = depth; i < nums.size(); ++i) {      //继续往深处搜索
                onePath.push_back(nums[i]);
                DFS(nums, i + 1);                          
                onePath.pop_back();                        //DFS回溯都是对称的,所以要恢复现场
            }
        }
    };
    

    方法二(二进制位运算)

    对于长度为n的数组,我们可以枚举所有长度为n的二进制串,并与数组元素进行与运算,
    二进制串中的0表示子集不选这个数,1表示子集选这个数,
    这样就直接枚举了所有的子集。

    class Solution {
    public:
        vector<vector<int>> subsets(vector<int>& nums) {
            vector<vector<int>> res;
            for(int i = 0; i < 1 << nums.size(); ++i) {            //枚举i从 0 ~ 2的nums.size()-1次方减一
                vector<int> oneSubset;
                for(int j = 0; j < nums.size(); ++j) {              //二进制串的长度是nums.size(),所以我们要逐位看看当前二进制串的各个位是0还是1(表示选还是不选)
                    if((i >> j) & 1) {                              //判断i的二进制第j位是否为1,要把i右移j位与1做与运算
                        oneSubset.push_back(nums[j]);               //如果是1,说明选第j个数,子集加上nums[j]
                    }
                }
                res.push_back(oneSubset);                        //甭管现在子集是啥,肯定是原来没有的(每个二进制子串都不同),所以把子集加入res数组,安排!
            }
            return res;
        }
    };
    
  • 相关阅读:
    修饰符
    Flex—鼠标样式设置
    代码审查――为可读性努力的巨大能量
    防火门、防盗门、安全门、实木门、单元门、智能门、装甲门、复合门
    表单设计器—开篇和环境
    DB2 9.5在英文版win7上Control Center菜单栏乱码问题解决
    Resin2.1与 IIS 整合
    Flex/AIR控件字体样式设置
    表单设计器—HTML元素操作
    学习ORACLE网址
  • 原文地址:https://www.cnblogs.com/linrj/p/13237356.html
Copyright © 2020-2023  润新知