前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >leetcode题解 | 78. 子集

leetcode题解 | 78. 子集

作者头像
ACM算法日常
发布2018-08-07 19:47:45
6780
发布2018-08-07 19:47:45
举报
文章被收录于专栏:ACM算法日常ACM算法日常

里程碑:第一百篇文章

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

代码语言:javascript
复制
输入: nums = [1,2,3]
输出:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

这个题目很容易想到使用DFS的方式来解决,因为组合的题容易产生转移方程,这样也是没有什么问题的。

对于数组(1,2,3),所有的子集正好是Cn0+Cn1+Cn2+...+Cnn,算出来也就是2的n次方。

凡是和2的n次方扯上关系的算法题,貌似都可以用位运算来试试!

对于数组(1,2,3),如果用位来表示,可以看成是111,而000表示空集,也就是说0表示不存在,1表示存在。

这个解法以前的一篇文章有类似的思路。公众号现在发了一百来篇文章,也忘了是哪篇了。

对于集合中的任意元素x,如果x包含进来,就表示为1,不包含,就表示为0。

而从0到2n-1的每次迭代,都表示一次变化,每一次变化都是集合中的一种。

代码语言:javascript
复制
int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) {
    *returnSize = pow(2, numsSize);
    int **result;
    int *colSize;
    //分配二级指针,这块内存是一个数组,每个数组元素都是一个一级指针
    result = (int**)malloc(sizeof(int*) * (*returnSize));
    colSize = (int**)malloc(sizeof(int*) * (*returnSize));

    //计算出所有的组合
    //所有的组合也就是0-(2^n-1)的位形式
    //如3,0-7: [000, 001, 010, 011, 100, 101, 110, 111]
    for (int i = 0; i < *returnSize; i++) {
        int x = i;
        int count = 0;

        while (x) {
            if (x & 1)
                count++;
            x >>= 1;
        }

        colSize[i] = count;
        //分配大小,这个for循环的作用仅仅只是分配好大小
        result[i] = (int*)malloc(sizeof(int) * (colSize[i]));
    }

    *columnSizes = colSize;

    for (int i = 0; i < *returnSize; i++) {
        int x = i;
        int col = 0;
        int j = 0;

        while (x) {
            //如果哪一位上是1,就记录一下这个位置
            if (x & 1) {
                result[i][col++] = nums[j];
            }
            j++;
            x >>= 1;
        }
    }
    return result;
}

int main(int argc, char **argv)
{
    int i, j;
    if (argc <= 1) {
        fprintf(stderr, "Usage: ./test array...\n");
        exit(-1);
    }
    int size = argc - 1;
    int *nums = malloc(size * sizeof(int));
    for (i = 0; i < size; i++) {
        nums[i] = atoi(argv[i + 1]);
    }
    int *sizes;
    int count;
    int **lists = subsets(nums, size, &sizes, &count);
    for (i = 0; i < count; i++) {
        for (j = 0; j < sizes[i]; j++) {
            printf("%d ", lists[i][j]);
        }
        printf("\n");
    }
    return 0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ACM算法日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档