# 方法一:位运算方式
元素有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