[LeetCode]78. 子集(位運算;回溯法待作)

題目

給定一組不含重複元素的整數數組 nums,返回該數組全部可能的子集(冪集)。數組

說明:解集不能包含重複的子集。網絡

示例:code

輸入: nums = [1,2,3]
輸出:
[
[3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []]leetcode

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/subsets
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。get

題解

方法一 位運算

  • 此方法僅限nums的長度爲32如下,不然溢出。
  • 對於長度爲len的數組nums={2,3,4,5},掩碼範圍[0,2^4),有2^4==1<<len
  • 對於每一個掩碼,掩碼爲1的位的nums元素加入當前所求子集中,((bitMask >> i) & 1)能夠判斷掩碼的哪些位爲1。故每條掩碼對應一個子集。

方法二 枚舉

  • 遍歷數組,每次,將當前全部子集都加上當前元素構成新的一些子集,加入當前子集集合中。

方法三 回溯

todo

回溯法待作。it

代碼

方法一 位運算

public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> subSetList = new LinkedList<>();
        int len = nums.length;
        int subSetCnt = 1 << len;// 子集數目
        for (int bitMask = 0; bitMask < subSetCnt; ++bitMask) {
            List<Integer> subSet = new LinkedList<>();
            for (int i = 0; i < len; ++i) {
                if (((bitMask >> i) & 1) == 1) { // 若是掩碼第(低)i位爲1
                    subSet.add(nums[i]);
                }
            }
            subSetList.add(subSet);
        }
        return subSetList;
    }

方法二 枚舉

public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> subSetList = new LinkedList<>();
        int len = nums.length;
        subSetList.add(new LinkedList<>());
        for (int i = 0; i < len; ++i) {
            int curSubSetCnt = subSetList.size();
            for (int j = 0; j < curSubSetCnt; ++j) { // 注意這裏用常數curSubSetCnt,保證只遍歷列表未加入這個元素以前的全部子集
                List<Integer> newSebSet = new LinkedList<>(subSetList.get(j));
                newSebSet.add(nums[i]);
                subSetList.add(newSebSet);
            }
        }
        return subSetList;
    }
相關文章
相關標籤/搜索