78.子集

2020/10/1

# 方法一:位运算方式

元素有n个,则子集个数是2的n次方,  
真子集个数:2^n -1,  
非空真子集个数:2^n-2  

1<<n ,1 * 2^n  
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int length = nums.length;
        List<List<Integer>> resultList = new ArrayList<>();
        for(int i= 0; i<(1<<length);i++){
            List<Integer> list = new ArrayList();
            for(int j= 0; j<length; j++){
                if(( i & 1<<j) != 0){
                    list.add(nums[length-1-j]);
                }
            }
            resultList.add(list);
        }
        return resultList;
    }
}

将内部for循环中j解释为数组索引

1. 数组[1,2,3]有3个元素,用3位字节表示,1表示当前子集存在、0表示不存在,如{1,3}就是101
2.  
|   0  |  1   |   2  |   3  |   4  |   5  |   6  |   7   |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ----  |
| 000  | 001  | 010  | 011  | 100  | 101  | 110  |  111  |
| {}   | {3}  | {2}  |{2,3} | {1}  |{1,3} |{1,2} |{1,2,3}|


以5举例,
101 和分别和 1、10、100 取&运算:
1. 当101 & 1  (即2^0,索引为0,但2^0用来判断数组最右端length-1-0的元素是否存在)不等于0,说明此位置(length-1-0)有元素占用,即001,也就是{3}(取nums[length-1-0])加入List
2. 当101 & 10 (即2^1,索引为1,但2^1用来判断数组length-1-1的元素是否存在)等于0,说明此位置没有元素占用  
3. 当101 & 100(即2^2,索引为2,但2^2用来判断数组length-1-2的元素是否存在)不等于0,说明此位置(length-1-2)有元素占用,即100,也就是{1}(取nums[length-1-2])加入List

# 方法二:回溯算法

Last Updated: 4/4/2024