前言:提前祝大家国庆快乐鸭~
题目描述
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)
示例:
思路
使用回溯法解决 —— 回溯法三步走:
- 递归参数:当前递归到的位置 index
- 递归终止条件:当前递归到的位置为数组长度 (可以不写,这也是循环结束条件)
- 单层逻辑
在下列循环中for(int i=index; i<nums.length; i++)
(index记录循环起点,如选过1后,只能在[2,3]中选)
list.add(nums[i]);
图解
代码
// 组合个数问题 —— 递归解法
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> list = new ArrayList<>();
backTrace2(ans, nums, list, 0);
return ans;
}
// index 记录选到第几个
public void backTrace2(List<List<Integer>> ans, int[] nums, List<Integer> list, int index){
ans.add(new ArrayList<>(list)); // 不需要剪枝
for(int i=index; i<nums.length; i++){
list.add(nums[i]);
backTrace2(ans, nums, list, i+1);
list.remove(list.size() - 1);
}
}
变式
题目描述
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例
思路
这题和上题思路类似,只是多了递归结束条件 list.size() == k
(其实可以看成组合问题的剪枝——只要长度为k的结果)
图解
代码
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> ans = new ArrayList<>();
List<Integer> list = new ArrayList<>();
backTrace4(ans, n, list, 1, k);
return ans;
}
public void backTrace4(List<List<Integer>> ans, int n, List<Integer> list, int index, int k){
if(list.size() == k){ // 结束
ans.add(new ArrayList<>(list));
return;
}
for(int i=index; i<=n; i++){
list.add(i);
backTrace4(ans, n, list, i+1, k);
list.remove(list.size() - 1);
}
}
注释:大家可以使用dubug功能,看看算法的执行情况,有助于理解~~