78. サブセット - バイナリ配置方法の賢い使い方
整数配列 nums が与えられていますが、配列内の要素はそれぞれ異なります。この配列の可能なすべてのサブセット (べき集合) を返します。
ソリューション セットには重複したサブセットを含めることはできません。ソリューション セットは任意の順序で返すことができます。
例 1:
入力: nums = [1,2,3]
出力: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1, 2,3]]
例 2:
入力: nums = [0]
出力: [[],[0]]
ブロガーは、この質問は学ぶ価値があると考えています。この質問は、セットのサブセットを作成する方法を教えてくれるからです。ここでの優れた方法は、各数値の 2 進数 01 の配置が異なるということです。このようにして、すべての数値を列挙できます。たとえば、セットのサイズが 3 で、その部分集合の数が 8 の場合、0 ~ 7 の 7 つの数字に対して 01 の 2 進数が 8 種類存在し、それが 1 に対応します。場所からデータを抽出すると、問題をうまく解決できます。
解決策のコードは次のとおりです。
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int len=1;
for(int i=0;i<numsSize;i++){
len=len*2;
}
int **re=(int **)malloc(sizeof(int*)*len);
(* returnColumnSizes)=(int *)malloc(sizeof(int)*len);
* returnSize=len;
for(int i=0;i<len;i++){
(* returnColumnSizes)[i]=0;
re[i]=(int*)malloc(sizeof(int)*numsSize);
}
int psize=0;
for(int i=0;i<len;i++){
int size=0;
int num=i;
for(int j=0;num>0;j++){
if(num&1){
printf(" %d %d %d|",psize,size,j);
re[psize][size++]=nums[j];
}
num=num>>1;
}
(* returnColumnSizes)[psize]=size;
psize++;
}
return re;
}
これは素晴らしいトピックなので、ぜひ皆さんにも勉強することをお勧めします。