• 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。