求包含不同整数的集合所有的子集

Lintcode地址:http://www.lintcode.com/zh-cn/problem/subsets/
样例:
如果 S = [1,2,3],有如下的解:

[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

常规思路:递归添加元素,元素有出现和不出现2种状态,用1个数组保存该状态:

    public List> subsets(int[] nums) {
        int len = nums.length;
        boolean[] marks = new boolean[len];
        List> result = new ArrayList<>();
        addSub(result, nums, marks, 0, len);
        return result;
    }

    private void addSub(List> result, int[] nums, boolean[] marks, int start, int len) {
        if (start >= len) {
            List subList = new ArrayList<>();
            for (int i = 0; i < len; i++) {
                if (marks[i]) {
                    subList.add(nums[i]);
                }
            }
            result.add(subList);
        } else {
            marks[start] = true;
            addSub(result, nums, marks, start + 1, len);
            marks[start] = false;
            addSub(result, nums, marks, start + 1, len);
        }
    }

在网上看到了另一种更简洁的算法,用二进制整数各位的值表示元素是否出现的状态,循环加1该整数即可输出所有子集。

    public List> subsets(int[] nums) {
        int len = nums.length;
        List> result = new ArrayList<>();
        // 子集总数为2的len次幂
        for (int k = 0; k < (1 << len); k++) {
            List sub = new ArrayList<>();
            for (int j = 0; j < len; j++) {
                // 第j位为1表示对应的数字出现在子集中
                if (((k >> j) & 1) == 1) {
                    sub.add(nums[j]);
                }
            }
            result.add(sub);
        }
        return result;
    }

你可能感兴趣的:(求包含不同整数的集合所有的子集)