又是一个回溯问题。
- 递归参数:当前遍历数组索引,当前的路径
- 返回条件:索引为数组末尾
- 递归工作:加入或者不加入索引指向的元素到当前路径
- 返回参数:无
算法复杂度
- O ( n ∗ 2 n ) O(n*2^n) O(n∗2n)有 2 n 2^n 2n, n n n为数组长度,因为得到一条路径需要 O ( n ) O(n) O(n)的时间
- O ( n ) O(n) O(n),递归深度为 n n n
class Solution {
// 用于返回结果
List<List<Integer>> res = new LinkedList();
int[] nums;
public List<List<Integer>> subsets(int[] nums) {
this.nums = nums;
subsets(0, new LinkedList<Integer>());
return res;
}
private void subsets(int i, LinkedList<Integer> curPath){
// 访问到最后一个节点,加入路径
if(i == nums.length){
// 不能这么写res.add(curPath);
// 要新建一个对象
res.add(new LinkedList(curPath));
return;
}
// 进行回溯,加入和不加入这条路径
curPath.add(nums[i]);
subsets(i + 1, curPath);
curPath.removeLast();
subsets(i + 1, curPath);
}
}
当然,也可以这么写
class Solution {
List<List<Integer>> res = new LinkedList();
int[] nums;
public List<List<Integer>> subsets(int[] nums) {
this.nums = nums;
subsets(0, new LinkedList<Integer>());
// 访问数组默认为false;
return res;
}
private void subsets(int start, LinkedList<Integer> curPath){
// 加入当前路径
res.add(new LinkedList(curPath));
// 遍历每个元素,每个元素先加入路径递归,然后再移除
for(int i = start; i < nums.length; i++){
curPath.add(nums[i]);
subsets(i + 1, curPath);
curPath.removeLast();
}
}
}