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二维数组中。
这个想法不是一开始想到的,我本想按住第一位,用动态规划找后面所有可能,结果阴差阳错的想到的,没想到这么好使,希望我能在关键时候有这运气吧。