当前位置:网站首页>leetcode 剑指 Offer 12. 矩阵中的路径
leetcode 剑指 Offer 12. 矩阵中的路径
2022-07-30 08:52:00 【kt1776133839】
题目描述:
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

样例:
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
提示:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成
解题思路:
本问题是典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝 解决。
深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。

DFS 解析:
递归参数: 当前元素在矩阵 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 ,代表是否搜索到目标字符串。
使用空字符(Python: '' , Java/C++: '\0' )做标记是为了防止标记字符与矩阵原有字符重复。当存在重复时,此算法会将矩阵原有字符认作标记字符,从而出现错误。
Java程序:
class Solution {
public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; j++) {
if(dfs(board, words, i, j, 0)) return true;
}
}
return false;
}
boolean dfs(char[][] board, char[] word, int i, int j, int k) {
if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]) return false;
if(k == word.length - 1) return true;
board[i][j] = '\0';
boolean res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = word[k];
return res;
}
}
边栏推荐
- 342 · 山谷序列
- The sword refers to offer 48: the longest non-repeating substring
- 涛思 TDengine 2.6+优化参数
- LeetCode二叉树系列——94.二叉树的中序遍历
- Only after such a stage of development can digital retail have a new evolution
- qsort 函数的使用及其模拟实现
- Unable to locate the program input point ucrtbase.abort on the dynamic link library api-ms-win-crt-runtime-|1-1-0.dll
- 利用R语言读取csv文件入一个数据框,然后查看各列的属性。
- js currying
- Oracle 创建和操作表
猜你喜欢

新手必备!最全电路基础知识讲解

How to use Jmeter to carry out high concurrency in scenarios such as panic buying and seckill?

conda 导出/导出配置好的虚拟环境

浅论各种调试接口(JTAG、SWD、RDI、Jlink、Ulink、STlink)的区别

02-课程发布

仿牛客网项目第二章:开发社区登录模块(详细步骤和思路)

Using IN in MySQL will not go through index analysis and solutions

宝塔搭建DM企业建站系统源码实测

【愚公系列】2022年07月 Go教学课程 021-Go容器之切片操作

Access to display the data
随机推荐
编程界的“躲猫猫”比赛 | 每日趣闻
如何避免CMDB沦为数据孤岛?
虚幻引擎图文笔记:could not be compiled. Try rebuilding from source manually.问题的解决
69. Sqrt(x)x 的平方根
树莓派_烧写Raspberry官方镜像系统
Field interpretation under "Surgical variables (RX SUMM-SURG OTH REG/DIS)" in SEER database
The sword refers to offer 48: the longest non-repeating substring
【云原生】Kubernetes入门详细讲解
Network/Information Security Top Journal and Related Journals Conference
Unreal Engine Graphic Notes: could not be compiled. Try rebuilding from source manually. Problem solving
2022杭电多校第二场
硬件工程师
2022杭电多校第一场
LeetCode二叉树系列——94.二叉树的中序遍历
How to use Jmeter to carry out high concurrency in scenarios such as panic buying and seckill?
js currying
Detailed description of iperf3 parameter options
C语言经典练习题(3)——“汉诺塔(Hanoi)“
电源完整性基础知识
The FPGA based protocol 2: the I2C read and write E squared PROM