组合 子集 排列 总结

总结:

所有的Deque 类型或者 LinkedList类型的变量 统计长度都是使用 path.size() 来实现的

递归中到下一层 位置变更为 i + 1,而不是 begin + 1

如果出现给定的数组是重复的情况,则首先要进行排序,然后执行去重

组合问题和子集问题需要设置begin位置,而排列问题不需要设置begin 位置

组合问题

  1. 对于组合问题,关键要注意的是,若是要求不重复,则在回溯中的下一个位置是 i + 1 ,注意超过范围则剪枝
  2. 还有就是若给定的数组中包含重复的元素 需要进行去重 而且需要排序 如下
    if(i > begin && candidates[i] == candidates[i - 1]) continue;
    对于组合问题:组合总和中需要排序组合总和II 也需要排序

子集问题

  1. 关键是在回溯的一开始位置就将path 加入到res 中
  2. 若有重复元素执行去重 if(i > begin && nums[i] == nums[i - 1]) continue 还需要排序

排列问题

  1. 排列问题需要设置used 数组,记录之前是否使用过某位置的元素
  2. 对于普通的排列问题,当 if(used[i]) 则 continue
  3. 对于有重复元素的排列问题, if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) continue 即检测上一个位置是否已经被释放,只有当 if(used[i] == false) 即当前位置为false 的时候,才执行递归操作

对于path 的类型初始化

初始化的方式 如下 都是可以的,但是要注意在定义的recur 函数中,也要注意一致化的问题

  1. LinkedList< Integer> path = new LinkedList<>();
  2. Deque< Integer> path = new LinkedList<>();
    在这里插入图片描述

组合

普通组合问题

在这里插入图片描述

  1. 这种类型是最基础的类型,在回溯的终止条件中,值需要判断path 的 size 是否和 k 相等即可,相等则使用res 保存当前的 path。
  2. 在递归过程中 ,递归之前加入 ,递归之后撤销

对于计算总和的题目,若给定了数组则都要进行排序

组合总和I

在这里插入图片描述

  1. 此时需要计算组合的sum 为 target的情况
  2. 只有当sum == target 的时候,才保存当前的path
  3. for 循环中,先判断sum 是否 是 大于 target ,若是,则break
  4. 递归之前 sum += candidates[i] 然后path 添加,递归之后 撤销上述两项

组合总和II

在这里插入图片描述

  1. 要求每个数组中的值 ,只能使用一次
  2. 也是先排序,然后此题没有定义sum,于是采用的是target 自动减去值得方式,最后的截止条件是,当target == 0 的时候,使用res 来保存当前的path
  3. 在for 循环中,需要进行 判断当前的 元素是否和上一个元素相等的操作 (去重)

组合总和III

在这里插入图片描述

  1. 此题没有给定数组,将数字限定1-9 而且不能重复使用
  2. 要求 实现 k 个数字的和 为 n## 标题
  3. 因此截止条件不仅要写sum == n 还要满足path.size() == k
  4. for 循环的递归之前也是两步,先计算sum ,再计算 path ,递归之后撤销
  5. 因为是不重复使用,则递归时,每次开始的位置 是 i + 1

子集

子集I

在这里插入图片描述

  1. 满足不重复,而且不限制和为多少,只是统计有多少个子集
  2. 进入回溯函数的时候,先使用res 来 保存path
  3. 截止:当子集的长度越界的时候,即子集的开始位置 和数组长度相等的时候
  4. for循环和之前类似

子集II

在这里插入图片描述

  1. 次问题和子集I 的不同处是,此时给定的数组内有重复元素,但是要求结果不能包含重复的子集
  2. 当遇到出现重复元素,但是要满足结果不包含重复元素的问题,关键位置是进行排序
  3. 在for 循环中,需要执行判断 nums[i] == nums[i - 1]

排列

全排列I

  1. 给定的数组是不包含重复元素的,要求返回所有的排列
  2. 这种排列问题要设置used 数组,来判断当前元素是否被使用过
  3. 如果被使用过,则直接continue,
    若没有则先used[i] =true; 以及 path.addLast(nums[i]);
    之后执行撤销

全排列II

在这里插入图片描述

  1. 此题与上一题的不同是:给定的数组内包含了重复元素,但是要求返回不重复的排列
  2. 对于这种问题,也是要先排序
  3. 也是要使用used数组,但是要添加上出重处理
  4. 在for 内 nums[i] == nums[i - 1] && used[i - 1] == false 时说明上一个位置已经被使用过,因为其used 值为FALSE(被释放了)则continue
  5. 只有当 当前元素的used 为FALSE的时候,才执行 path 添加和used修改的操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值