Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法1:回溯
void backtrack(int *nums, int numsSize, int **ret, int *retIdx, int **returnColumnSizes, int idx, int *output, int *out_idx)
{
if(idx == numsSize)
{
int i;
int k = *retIdx;
for(i = 0; i < *out_idx; ++i)
{
ret[k][i] = output[i];
}
(*returnColumnSizes)[k] = *out_idx;
*retIdx += 1;
return;
}
output[*out_idx] = nums[idx];
*out_idx += 1;
backtrack(nums, numsSize, ret, retIdx, returnColumnSizes, idx + 1, output, out_idx);
*out_idx -= 1;
backtrack(nums, numsSize, ret, retIdx, returnColumnSizes, idx + 1, output, out_idx);
}
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int totalSize = 1;
int tmp = numsSize;
while( tmp-- > 0)
{
totalSize *= 2;
}
*returnSize = totalSize;
int **ret = (int **)malloc(sizeof(int *) * totalSize);
int *buffer = (int *)malloc(sizeof(int) * numsSize * totalSize);
int i;
for(i = 0; i < totalSize; ++i)
{
ret[i] = buffer + i * numsSize;
}
*returnColumnSizes = (int *)malloc(sizeof(int) * totalSize);
int *output = (int *)malloc(sizeof(int) * numsSize);
int out_idx = 0;
*returnSize = 0;
backtrack(nums, numsSize, ret, returnSize, returnColumnSizes, 0, output, &out_idx);
return ret;
}
回溯2:
/**
* 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().
*/
void backtrack(int *nums, int numsSize, int **ret, int *retIdx, int **returnColumnSizes, int idx, int *output, int *output_idx)
{
int i;
int k = *retIdx;
for(i = 0; i < *output_idx; ++i)
{
ret[k][i] = output[i];
printf("%d ", output[i]);
}
printf("\n");
(*returnColumnSizes)[k] = *output_idx;
*retIdx += 1;
for(i = idx; i < numsSize; ++i)
{
output[*output_idx] = nums[i];
*output_idx += 1;
backtrack(nums, numsSize, ret, retIdx, returnColumnSizes, i + 1, output, output_idx);
*output_idx -= 1;
}
}
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int totalSize = 1;
int tmp = numsSize;
while( tmp-- > 0)
{
totalSize *= 2;
}
*returnSize = totalSize;
int **ret = (int **)malloc(sizeof(int *) * totalSize);
int *buffer = (int *)malloc(sizeof(int) * numsSize * totalSize);
int i;
for(i = 0; i < totalSize; ++i)
{
ret[i] = buffer + i * numsSize;
}
*returnColumnSizes = (int *)malloc(sizeof(int) * totalSize);
int *output = (int *)malloc(sizeof(int) * numsSize);
*returnSize = 0;
int output_idx = 0;
backtrack(nums, numsSize, ret, returnSize, returnColumnSizes, 0, output, &output_idx);
return ret;
}
3. 位运算解法
/**
* 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().
*/
void backtrack(int *nums, int numsSize, int **ret, int *retIdx, int **returnColumnSizes)
{
int *output = (int *)malloc(sizeof(int) * numsSize);
int idx;
int i, j;
for(i = 0; i < (1 << numsSize); ++i)
{
idx = 0;
int j = i;
int k = 0;
while(j > 0)
{
if(j &1 == 1)
{
output[idx++] = nums[k];
}
++k;
j = (j >> 1);
}
for(k = 0; k < idx; ++k)
{
ret[*retIdx][k] = output[k];
}
(*returnColumnSizes)[*retIdx] = idx;
*retIdx += 1;
}
}
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int totalSize = 1;
int tmp = numsSize;
while( tmp-- > 0)
{
totalSize *= 2;
}
*returnSize = totalSize;
int **ret = (int **)malloc(sizeof(int *) * totalSize);
int *buffer = (int *)malloc(sizeof(int) * numsSize * totalSize);
int i;
for(i = 0; i < totalSize; ++i)
{
ret[i] = buffer + i * numsSize;
}
*returnColumnSizes = (int *)malloc(sizeof(int) * totalSize);
int *output = (int *)malloc(sizeof(int) * numsSize);
*returnSize = 0;
int output_idx = 0;
backtrack(nums, numsSize, ret, returnSize, returnColumnSizes);
return ret;
}
图引用自