1. 程式人生 > 其它 >網路損傷儀WANsim的簡單使用方式

網路損傷儀WANsim的簡單使用方式

78. 子集

知識點:陣列;位運算;

題目描述

給你一個整數陣列 nums ,陣列中的元素 互不相同 。返回該陣列所有可能的子集(冪集)。

解集 不能 包含重複的子集。你可以按 任意順序 返回解集。

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

輸入:nums = [0]
輸出:[[],[0]]

解法一:迭代

這道題目可以用迭代的方式去解,首先在答案中新增空集,然後每遍歷一個元素,就是把答案中已有的集合在,末尾追加元素。比如例1,遍歷1的時候,在空集後追加1.遍歷2的時候在答案中的集合空集和1後追加2,形成2和1,2;依次類推;

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        res.add(list);
        for(int num : nums){
            for(int i = 0; i < res.size(); i++){
                List<Integer> temp = new ArrayList<>(res.get(i));
                temp.add(num);  //在每個集合後新增新元素;
                res.add(temp);
            }
        }
        return res;
    }
}

解法二:位運算

有3個元素,那最後我們得到的子集個數一定是8個,也就是2^3個,想一下我們其實可以用3位的0,1二進位制表示,哪一位上為1就對應哪一位上被選中,比如001,代表3,011代表2,3,000代表空集;這樣就把所有的子集都找到了。

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        int len = 1 << n;  //一共有多少個子集;
        List<List<Integer>> res = new ArrayList<>();
        for(int i = 0; i < len; i++){
            List<Integer> list = new ArrayList<>();
            for(int j = 0; j < n; j++){
                if(((i >> j) & 1) == 0){
                    list.add(nums[j]);  //哪位上為1選中哪位;
                }
            }
            res.add(list);
        }
        return res;
    }
}