回溯算法-刷题笔记

基础

回溯的本质是穷举,一般适用于组合、切割、子集、排列、棋盘等问题。

回溯问题抽象为树形结构,for循环-树层,递归-树枝

回溯法模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

77.组合

  1. 参数:n, k, startIndex(防止重复的数字出现)
  2. 递归结束条件,单条路径收集数字组合size==k,结果集收集,终止
  3. 单条递归逻辑:防止重复出现startInddex+1

216. 组合总和 III

  1. 终止条件:sum==targetSum,结果集收集
  2. 用sum统计每个数字之后,作为参数传递到递归函数

17. 电话号码的字母组合

  1. 首先给定,每个按键对应的字符串,string数组列举出来
  2. string数组用来收集结果,string s收集单条路径的结果
  3. 这里不需要startIndex来控制重复出现的次数,但是需要一个index来控制输入字符串中每个数字的索引,先通过index找出输入字符串digits对应的按键,根据对应的按键找到对应的字符串
  4. 开始for循环遍历,边界是按键字符串的大小,递归时,index+1

39. 组合总和

  1. 题目要求可以重复读取,startIndex不用+1操作
  2. 用sum统计数组中的数字之和,当sum==target时,存入结果集

40. 组合总和 II

  1. 题目要求不能重复,used数组用来解决树层和树枝上的去重
  2. used[i - 1] == true,说明同一树枝candidates[i - 1]使用过, used[i - 1] == false,说明同一树层candidates[i - 1]使用过
  3. 回溯之前,需要进行判断,同一树层使用过的元素跳过
  4. 回溯前:sum+,单条路径收集,used=true
  5. 回溯后:sum-,单条路径pop,used=false

131.分割回文串

  1. 终止条件:startIndex>=s.size(),存入结果集
  2. for循环遍历,回溯之前,判断是否回文串,截取字符串存入单条路径收集,不是回文,跳过
  3. 回溯参数,起始索引+1
  4. 判断回文:双指针指向字符串起始位置和结束位置,同时遍历,如果索引处的值不相等就不是回文,否则是回文

93.复原IP地址

  1. IP地址以逗点数量作为分割结束的条件,一个完整的IP地址有3个逗点
  2. 回溯参数,字符串,startIndex,记录逗点数量
  3. 单层逻辑,先判断子串是否合法, 如果合法,在字符之后加逗点,开始回溯,进行下一个字符的判断
  4. 判断字符串是否合法,参数左右区间,以及字符串,遇到0开头的的数字不合法,遇到非数字字符不合法,如果大于255了不合法

78.子集

  1. 每条路径上都收集结果,并不是叶子节点才收集,回溯一开始就收集结果集

90.子集II

  1. 树层去重,树枝可以重复,used数组树层去重
  2. 如果nums[i-1]==nums[i]&&used[i-1]==false,同一树层使用过,continue,跳过
  3. 单条路径收集,used置为true,开始回溯,索引i+1

491.递增子序列

  1. 题目要求不重复,unordered_set树层去重
  2. 当前元素小于单条路径的最后一个元素或者uset集合没有当前重复的元素,就跳过

46.全排列

  1. 叶子节点收集结果集,used数组去重,used[i] == true,树层去重

47.全排列 II

  1. used数组去重,i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false树层去重

51. N皇后

  1. 棋盘是否合法:不能同行,不能同列,不能斜对角线
  2. 回溯参数:棋盘大小n,行数row,字符串
  3. 终止条件:如果row==n,说明到达最大行,收集结果集
  4. 单层逻辑:不用同行进行比较,在for循环遍历时已经同行比较了
  5. chessboard[row][col] = 'Q'; // 放置皇后;chessboard[row][col] = '.'; // 回溯,撤销皇后
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值