回溯算法总结

回溯算法

回溯+递归,本质是穷举,虽有剪枝操作,总体效率较低。一般分为:①组合类型②分割类型③子集类型④排列类型⑤矩阵类型。可抽象为树结构,在集合中递归查找需要的子集。解题的时候掌握部分模板,for循环横向遍历,递归纵向遍历,去重方法,优化剪枝,最好自己画一棵树方便理解。

解题思路:

1、组合类型:#77组合 #39,40,216数组总和Ⅰ,Ⅱ,Ⅲ #17电话号码字母组合

77,216:返回1–n所有k个数组合,n等于树宽,k等于树深;确定参数,除了n和k,加入start记录从何开始遍历;终止条件,放入vector个数等于k。216注意终止条件

39,40:找出所有和等于target的组合;终止条件,大于target返回,等于target收录。注意限制条件,当数组无重复元素,数字无限重复选取时,递归时i不用+1。当有重复元素,数字只能使用一次时,需要排序去重,同一层不可重复,同一树枝可以重复。

17:使用一个hashmap或者数组记录对应数字和字母。多个集合,之间互不影响,不需要start,需要一个depth记录遍历到哪个数字。

2、分割类型:#131切割字符串返回回文串 #复原IP地址。

131:主要问题是如何切割,何时终止,截取子串,判断回文。加入start作为切割线,切割线大于等于字符串长度时,找到一组。判断回文时,满足就复制子字符串,不满足记得continue。回文判断使用双指针。

93:加入start记录下一次分割位置,pointnum记录‘.’个数,四段用完所有数字,满足有效IP地址条件:每个整数位于 0 到 255 之间组成,且不能含有前导 0。

3、子集类型:#78子集 #90子集Ⅱ。子集找树的所有节点,组合分割找树叶子节点。

78,90:子集算基本的模板题,当包含重复元素时,排序去重,(同数组总和Ⅱ)

if(i > start&& nums[i] == nums[i - 1])continue;
491:递增子序列,如果是递增的就是子集问题,但是我们不可以进行排序,需要自己去比较前后元素,set/数组去重。

4、排列类型:#46全排列 ⅠⅡ。处理排列问题就不使用start,有序的。

46:不按字典顺序输出可以:

swap(nums[i], nums[depth]); //进行回溯
一般是使用数组去重:

if (i > 0 && nums[i] == nums[i - 1] && use[i - 1] == false) continue;

5、矩阵类型:#37 解数独 #N皇后

51、N皇后:首先理解皇后的规则得到约束条件,不能同行同列同斜线。问题转化为一棵树,把握约束条件不断插入,到叶节点就是结果。不同斜线的时候分左上45°和右上45°。for循环控制宽度,递归控制深度。

37、解数独:二维递归,在N皇后基础上加上一层循环。同样有三个约束条件,同行同列9宫格都不能重复。没有终止条件,因为要给每日空填值,遍历整棵树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值