力扣算法题-78.子集 C语言实现+Java实现

题目

给定一组不含重复元素的整数数组 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;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值