Given a set of distinct integers, return all possible subsets.
Notice
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
Example
If S = [1,2,3]
, a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
Java
public class Solution {
/*
* @param nums: A set of numbers
* @return: A list of lists
*/
public List<List<Integer>> subsets(int[] nums) {
// write your code here
List<List<Integer>> results = new ArrayList<>(); //先创建的是results的大集合,这个集合装的是List<Integer>,所以要注意泛型为空或者为List<Integer>,前后的泛型必须一致,或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
//空检测
if(nums == null) {
return results;
}
if(nums.length == 0) {
results.add(new ArrayList<Integer>());
return results;
}
Arrays.sort(nums);
dfsHelper(new ArrayList<Integer>(), nums, 0, results); //寻找所有以[]集合开头的子集,即找到所有的子集。(从nums数组的0位开始寻找)
return results;
}
//递归三要素
//1.递归的定义:在 Nums 中找到所有以 subset 开头的集合并放到 results
private void dfsHelper(ArrayList<Integer> subset,
int[] nums,
int startIndex,
List<List<Integer>> results) {
//2.递归的拆解
//deep copy
//results.add(subset);
results.add(new ArrayList<Integer>(subset)); //这个地方不能写成results.add(subset);不能传递引用过去,需要复制一份进去,不然之后对subset进行的更改也会导致results中内容的随之更改
//从startIndex开始往subset中扔数,扔到不能扔了之后就返回上一层,startIndex加1
for(int i = startIndex; i < nums.length; i++) {
//[ ] -> [1]
subset.add(nums[i]);
//寻找所有以[1]开头的集合,并扔到results
dfsHelper(subset, nums, i + 1, results);
//[1] -> [ ] 回溯,返回本层的初始结果,方便下一轮循环往里添加新的数据
subset.remove(subset.size() - 1);
}
// 3.递归的出口
// return; 由于本程序在不能循环的时候会自动退出,因此不需要递归的出口,但是如果遇到排列问题,出口可能就变为达到某一数量就可返回。
}
}