解法一:
每次遍历nums数组,都有两种选择选择这位数和不选择这位数,递归此过程直到nums遍历结束,最后拿到了所有子集可能。
import java.util.ArrayList;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length == 0){
return res;
}
process(nums,0,new ArrayList<>(),res);
return res;
}
public void process(int[] nums,int step,List<Integer> list,List<List<Integer>> res){
if(step == nums.length){
res.add(new ArrayList(list));
return ;
}
//不选择这位数的递归
process(nums,step+1,list,res);
/*
选择有这位数的递归,
存储子集不能是同一个集合,否则后面给集合的赋值会覆盖掉前面的保存的结果
*/
List<Integer> li = new ArrayList<>(list);
li.add(nums[step]);
//不能是step自增,不管是向下递归还是向上回退,step的值不会变,一直指向的都是这一层
process(nums,step+1,li,res);
}
}
解法二:
- 单层循环求得的是所有以start为开头的子集。
- 遍历整个数组,穷尽了以每个元素为开头的子集,加上空集就构成全部子集。
- 参数
变量start作为标记每层递归需要加入的起始元素 - 单层遍历
在现有的li集合上每次添加一个从start到结尾之间的元素,这样便是新的子集 - 终止条件
start等于数组的长度
class Solution {
List<Integer> li = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums,0);
res.add(new ArrayList<>());
return res;
}
public void backTracking (int[] nums, int start){
if(start >= nums.length){
return ;
}
for(int i = start; i < nums.length; i++){
li.add(nums[i]);
res.add(new ArrayList<>(li));
backTracking(nums,i+1);
li.remove(li.size()-1);
}
}
}
解法三:
每次便利nums都是在原来的结果上,添加上这次便利的结果构成新的子集,然后添加进最终结果,直到nums遍历结束。
//迭代解法
import java.util.ArrayList;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<Integer>());
for(int i = 0;i < nums.length;i++){
int len = res.size();
for(int j = 0; j < len;j++){
List<Integer> tmp = new ArrayList<>(res.get(j));
tmp.add(nums[i]);
res.add(tmp);
/*
不能写成
List<Integer> tmp = new ArrayList<>();
tmp = res.get(j);
tmp.add(nums[i]);
res.add(tmp);
虽然新建了List<Integer>变量tmp,但是tmp = res.get(j)使得tmp又指向了res.get(j)
后面的tmp.add(nums[i]),实际上是对res.get(j)进行添加,把原来已经保存的结果又给改变了,所以报错。
*/
}
}
return res;
}
}
//递归解法
import java.util.ArrayList;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
res.add(new ArrayList<Integer>());
int step = 0;
process(nums,step,res);
return res;
}
public void process(int [] nums,int step,List<List<Integer>> res){
if(step == nums.length){
return ;
}
int size = res.size();
for(int i =0;i < size;i++){
List<Integer> li = new ArrayList<>(res.get(i));
li.add(nums[step]);
res.add(li);
}
process(nums,++step,res);
return ;
}
}