leecode第七十八题(子集)

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<int> bool_num;
        vector<vector<int>> res;
        int len=nums.size();
        
        if(len==0)//特殊情况处理
            return res;
        
        for(int i=0;i<len;i++)//建立一个全零,长度为len的数组,用于模拟二进制加法,其中的1提供索引位置
            bool_num.push_back(0);

        for(int i=0;i<pow(2,len);i++)
        {
            vector<int> item;
            for(int j=0;j<len;j++)//把不为0的数字推入一个崭新的item
            {
                if(bool_num[j]!=0)
                    item.push_back(nums[j]);
            }
            res.push_back(item);
            
            bool_num[len-1]+=1;//模拟二进制加法,目的是遍历K位所有可能的取值
            for(int j=len-1;j>0;j--)
            {                    
                if(bool_num[j]==2)
                {
                    bool_num[j]=0;
                    bool_num[j-1]+=1;
                }
                else
                    break;
            }
        }
        
        return res;
    }
};

分析:

这个算法本质是这样的:

给了一个K位的数组,他的组合应该是从

0:   [NULL]   [NULL]   [NULL]  ........ [NULL]

1:   [num1]   [num2]   [num3]  ........  [numK]

里面组合得到的。

文字描述:对每一个位置上可能选取0/1,分别代表空/实值,这样所有可能组合变为寻找K位二进制所有可能取值。

举例描述:有三位的【1,2,3】数组,我们遍历三位的二进制所有可能,其分别代表

000   []

001   [3]

010   [2]

011   [2,3]

100   [1]

101   [1,3]

110   [1,2]

111   [1,2,3]

然后我就一方面模拟二进制加法遍历K位所有可能,一方面根据当前二进制数索引并添加进res二维数组中。

这个想法不是一开始想到的,我本想按住第一位,用动态规划找后面所有可能,结果阴差阳错的想到的,没想到这么好使,希望我能在关键时候有这运气吧。

猜你喜欢

转载自www.cnblogs.com/CJT-blog/p/10601002.html