- 回溯真题
- 这几道真题可以作为笔试真题模板进行参考
- 感觉和LeetCode200、岛屿题是类似的模板
- 【回溯】2023B-找到它
- 注意,本题和LeetCode79. 单词搜索几乎完全一致,唯一的区别在于前者只要求判断是否能够找到该单词,本题还需要输出起始位置。
- 注意回溯的选择条件
- (nx,ny)必须满足以下三个条件,才可以继续进行回溯函数的递归调用
- 1. 不越界;2. 尚未检查过;3.在grid中的值grid[nx][ny]为word的下一个字符word[word_idx+1]
- 算法解析:
- 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。
- 终止条件:
- 返回 false : (1) 行或列索引越界 或 (2) 当前矩阵元素与目标字符不同 或 (3) 当前矩阵元素已访问过 ( (3) 可合并至 (2) ) 。
- 返回 true: k = len(word) - 1 ,即字符串 word 已全部匹配。
- 递推工作:
- 标记当前矩阵元素: 将 board[i][j] 修改为 空字符 '' ,代表此元素已访问过,防止之后搜索时重复访问。
- 搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。
- 还原当前矩阵元素: 将 board[i][j] 元素还原至初始值,即 word[k] 。
- 返回值: 返回布尔量 res ,代表是否搜索到目标字符串。
- 【回溯】华为2023秋招-中庸行者
- 本题数据规模较小,最多只有8 * 8 = 64个点,因此可以使用DFS回溯的方式枚举出所有路径。
- 回溯过程中有几个问题需要注意:
- 上下坡是不断交替切换的,故在回溯函数中可以设置一个布尔型标记isUp来表示下一步移动是上坡还是下坡
- 和常规的DFS有所不同,checkList的更新是需要回滚的,因为同一个点有可能通过不同路径反复走到
- 需要用一个变量path_len来记录当前路径长度的变化,可以直接将path_len+1作为回溯的参数传入
- 回溯调用的入口,需要同时考虑第一步是上坡还是下坡的情况,故对于每一个特定的点(i, j),其回溯入口都需要调用两次,分别设置isUp是True和False的情况。
- 【回溯】百度2021秋招-子序列中的k种字母
- 排列组合数学知识+哈希表+组合类的回溯问题
- 首先根据二项式定理计算各个字符ch所对应的仅包含ch的子序列的数量
- 再在m个字符中挑选k种字符,用组合类的回溯解法
- 最后计算仅包含k种字符的子序列
- 假设已经挑选出了k种字符,那么根据乘法原理,包含这k种字符的子序列的数目,为这k种字符中仅包含1种字符的子序列的数量的乘积。
- 作业
- LeetCode79、 单词搜索
- 算法解析:
- 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。
- 终止条件:
- 返回 false : (1) 行或列索引越界 或 (2) 当前矩阵元素与目标字符不同 或 (3) 当前矩阵元素已访问过 ( (3) 可合并至 (2) ) 。
- 返回 true: k = len(word) - 1 ,即字符串 word 已全部匹配。
- 递推工作:
- 标记当前矩阵元素: 将 board[i][j] 修改为 空字符 '' ,代表此元素已访问过,防止之后搜索时重复访问。
- 搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。
- 还原当前矩阵元素: 将 board[i][j] 元素还原至初始值,即 word[k] 。
- 返回值: 返回布尔量 res ,代表是否搜索到目标字符串。
- 算法解析:
- LeetCode 51、N 皇后(难题)
- 每个皇后可以攻击8个方向,每一行只能放一个皇后,也就是说得保证放置的每一行都可以有皇后。
- 假如按照图中位置摆放第一行的皇后,第二行蓝色放置在图中位置,那么第三行绿色就找不到位置放了,返回第二行,发现第四行找不到了,那么就返回....返回到第一行。
- 那么其实也是一种选择树了,出现错误的时候回到之前的状态,调用回溯算法!
- 构建两个二维数组,攻击数组(0表示不处于任何皇后的攻击位置),Queen数组
- 表达方式可以用行坐标数组和列坐标数组
- 做出选择:当attack[k][i]==0的时候,说明可以放置皇后,注意这里需要用一个temp=copy.deepcopy(attack)来保存attack,以便回溯。
- 递归操作k+1行
- 撤销选择:让attack=temp,然后再将queen数组里的queen[k][i]='.'
- LeetCode 37、解数独
- 也是一个不断选择,遇到错误返回上一状态的问题
- 每一行的每一个格子有1-9 9种选择,要判断是否可以填入当前的格子里
- 数独的三条规则:
- for i in range(9):
- if board[row][i] == c: return False
- if board[i][col] == c: return False
- if board[3 * (row // 3) + i // 3][3 * (col // 3) + i % 3] == c: return False
- for i in range(9):
- 【回溯】2023B-猜密码 组合型回溯 (可作为组合型真题模板)
- 组合型回溯问题,套用组合模板即可
- LeetCode79、 单词搜索