方法1:借助位运算进行判断
public class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result=new ArrayList<List<Integer>>();
int len=nums.length;
int digit=0;
for(int i=0;i<len;i++)
digit+=Math.pow(2,i); //如二进制序列“1111”,得到十进制数为15
int num=digit;
for(int i=0;i<=num;i++){ //4位的01排列共15种情况
List<Integer> temp=new ArrayList<Integer>();
for(int j=0;j<len;j++){ //针对每种情况按位与1进行与运算,如果为1,则取该位在数组中代表的数。
if((digit&1)==1) temp.add(nums[j]);
digit>>=1;
}
result.add(temp);
digit=num-i-1;
}
return result;
}
}
方法2:可以用递推的思想,观察S=[], S =[1], S = [1, 2] 时解的变化。以发现S=[1, 2] 的解就是 把S = [1]的所有解末尾添上2,然后再并上S = [1]里面的原有解。
public class Solution{
public List<List<Integer>> subsets(int[] S) {
if (S == null)
return null;
Arrays.sort(S);
List<List<Integer>> result = new ArrayList<List<Integer>>();
for (int i = 0; i < S.length; i++) {
List<List<Integer>> temp = new ArrayList<List<Integer>>();
//get sets that are already in result
for (List<Integer> a : result) {
temp.add(new ArrayList<Integer>(a));
}
//add S[i] to existing sets
for (List<Integer> a : temp) {
a.add(S[i]);
}
//add S[i] only as a set
List<Integer> single = new ArrayList<Integer>();
single.add(S[i]);
temp.add(single);
result.addAll(temp);
}
//add empty set
result.add(new ArrayList<Integer>());
return result;
}
}
方法3:基本思路循环+dfs,生成指定元素数目(0,1,2,…array.size()个元素)的组合。
public class Solution {
void dfs(int [] number_array, int start, int number, ArrayList<Integer> array, ArrayList<ArrayList<Integer>> result) {
if(number==array.size()) {
result.add(new ArrayList<Integer>(array));
return;
}
for(int i=start;i<number_array.length;i++) {
array.add(number_array[i]);
dfs(number_array,i+1,number,array,result);
array.remove(array.size()-1);
}
}
public ArrayList<ArrayList<Integer>> subsets(int[] S) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> array = new ArrayList<Integer>();
result.add(array);
if(S==null) {
return result;
}
Arrays.sort(S);
for(int i=1;i<=S.length;i++) {
array.clear();
dfs(S,0,i,array,result);
}
return result;
}
}