题目:
代码:
解法1,位运算
注意位运算的注释,易错点!!
class Solution {
// 官方解法1,位运算。
// 每一位在集合或不在,共有2^n种可能。我们用每种可能所代表的2进制序列来从数组中取数。
List<List<Integer>> ans=new ArrayList();
List<Integer> temp=new ArrayList();
public List<List<Integer>> subsets(int[] nums) {
int n=nums.length;
// 注意这里的位运算手法
for(int mask=0;mask<(1<<n);mask++){
temp.clear();
for(int i=0;i<n;i++){
// 注意,这里一定是!=0,不能写成==1,因为if判断可能结果有1,2,4,不止有1!!
// 最开始对位运算不熟悉写错了。例如:mask=1时,
// i会取1,2,4。判断分别为1&1(001&001=1),1&2(001&010=0),1&4(001&100=0)。
// mask=2时,判断分别为2&1(010&001=0),2&2(010&010=2),2&4(010&100=0)。
if((mask&(1<<i))!=0){
temp.add(nums[i]);
}
}
ans.add(new ArrayList<Integer>(temp));
}
return ans;
}
}
解法2,回溯
// 解法2
// 回溯是深度优先搜索中的一种情况,而深度优先搜索的实现是用递归。
// dfs,两种if
// 注意,这是回溯时深度优先搜索树的路径图:
// [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]
class Solution {
List<List<Integer>> ans=new ArrayList();
List<Integer> temp=new ArrayList();
public List<List<Integer>> subsets(int[] nums) {
dfs(0,nums);
return ans;
}
public void dfs(int cur,int[] nums){
if(cur==nums.length){
ans.add(new ArrayList<Integer>(temp));
return;
}
// 取当前元素
temp.add(nums[cur]);
dfs(cur+1,nums);
// 不取当前元素
temp.remove(temp.size()-1);
dfs(cur+1,nums);
}
}