-
2,12
- 不用判断 path 满了再添加集合
-
2.5
- 关键字:start 参数取代 isUsed 数组,backtrack 不需要结束条件(直接添加,for 作为隐形刹车结束条件存在(start 大于 nums 长度直接就不进入循环里了))
-
11.21
- 与全排列的第一个区别是:全排列使用uesd数组判断是否重复,子集是使用startIndex参数控制不回头(不重复)
- 第二个区别是,子集无论如何都会加入res结果中,但全排列需要判断path是否满了
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtrack(nums,0);
return res;
}
public void backtrack(int[] nums,int start){
res.add(new ArrayList<>(path));
for(int i=start;i<nums.length;i++){
path.add(nums[i]);
backtrack(nums,i+1);
path.remove(path.size()-1);
}
}
}
void backtrack(参数...) {
if (满足结束条件) {
记录结果;
return;
}
for (选择 in 可选列表) {
做选择;
backtrack(更新参数);
撤销选择;
}
}🔍 四、为什么要 start 参数? 这个参数控制“不回头”,防止重复。 子集问题要求 组合,不能重新选之前的数; 所以每层递归从 i = start 开始。 例如 [1,2,3]: 当选了 1 后,下一步只能从 [2,3] 选; 所以递归时传入 start = i + 1。