题目
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets
思路
题设前提:1、数组元素不重复;
解:
每个元素出现或不出现的情况进行组合,可以得到数据的所有子集,以示例为例,数组中有三个元素,数组长度为3。对于子集,每个元素存在出现和不出现两种情况,排列组合得到共有2^3=8个子集。
若数组长度为n,则子集数 = 2^n ;
集合[0,2^n-1] 每个数字可以代表一个子集,转化成二进制形式,可以得到子集。
以示例为例,集合[0,7]表示数组[1,2,3]中的八个子集,其中
0-000-[]
1-001-[1]
2-010-[2]
3-011-[1,2]
4-100-[3]
5-101-[1,3]
6-110-[2,3]
7-111-[1,2,3]
程序
C语言实现
/**
* 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().
*/
/*
nums 输入数组
numsSize 数组长度
*returnSize 返回数组长度
**returnColumnSizes 记录二级数组每个数组长度 的数组
*/
int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int* cols;
int** output;
int i,j,k,inum,icolnum;
inum = 2<<(numsSize-1);
*returnSize = inum;
/*分配内存,数组长度数组*/
*returnColumnSizes = (int*)(malloc(sizeof(int)*inum));
/*分配内存,数组指针数组*/
output = (int**)malloc(sizeof(int*)*inum);
for(i=0;i<inum;i++){
icolnum = 0;
/*先获取内层数组的长度*/
for(j=0;j<numsSize;j++){
/*判断二进制下j数的值是否为1*/
if(i>>j & 1){
icolnum++;
}
}
(*returnColumnSizes)[i] = icolnum;
/*分配内层数组内存*/
cols = (int*)malloc(sizeof(int)*icolnum);
/*内层数组赋值*/
for(j=0,k=0;j<numsSize;j++){
/*判断二进制下j数的值是否为1*/
if(i>>j & 1){
cols[k]=nums[j];
k++;
}
}
/*给数组指针数组赋值*/
output[i]=cols;
}
return output;
}
Java实现
class Solution {
public List<List<Integer>> subsets(int[] nums) {
int n= nums.length ;
List<List<Integer>> ret = new ArrayList();
for(int i = 0 ; i< 1<<n; i++){
List<Integer> list = new ArrayList();
for(int j=0; j< n; j++){
if(((i>>j) & 1) == 1){
list.add(nums[j]);
}
}
ret.add(list);
}
return ret;
}
}