题目描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

题目直达

力扣https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/

解题思路

本问题是典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝 解决。

  • 深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
  • 剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。


DFS解析:

  • 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k 。
  • 终止条件:
    • 返回False:行或列索引越界、当前矩阵元素与目标字符不同 、当前矩阵元素已访问过
    • 返回True:k = len(word) - 1 ,即字符串 word 已全部匹配。

递推工作:

  1. 标记当前矩阵元素: 将 board[i][j] 修改为 空字符 '' ,代表此元素已访问过,防止之后搜索时重复访问。
  2. 搜索下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,使用 或 连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果至 res 。

  3. 还原当前矩阵元素: 将 board[i][j] 元素还原至初始值,即 word[k] 。

返回值:返回布尔量 res ,代表是否搜索到目标字符串。

使用空字符(Python: '' , Java/C++: '\0' )做标记是为了防止标记字符与矩阵原有字符重复。当存在重复时,此算法会将矩阵原有字符认作标记字符,从而出现错误。

算法流程

C++代码实现

class Solution
{
public:bool exist(vector<vector<char>>& board, string word) {rows = board.size();  //字符矩阵的行数(0~rows-1)cols = board[0].size();   //字符矩阵的列数(0~cols-1)for(int i = 0; i < rows; i++) {for(int j = 0; j < cols; j++) {//当前元素在矩阵 board 中的行列索引 i 和 j//当前目标字符在 word 中的索引 k//从字符矩阵的左上角开始寻找,从上往下开始,看这个位置的矩阵元素是否是字符单词中的第一个字符if(dfs(board, word, i, j, 0)) return true;}}//遍历完了整个矩阵元素,依然没有找到一条合适的路,返回falsereturn false;}
private:int rows, cols;bool dfs(vector<vector<char>>& board, string word, int i, int j, int k) {//如果索引越界了,或者是当前位置的矩阵元素不等于目标匹配字符,返回falseif(i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]) return false;//能够到达这一步,证明索引没有越界,且当前位置在矩阵中的元素等于目标匹配字符//所以如果目标字符的索引为最后一个了,那肯定匹配成功了,直接返回trueif(k == word.size() - 1) return true;//标记当前矩阵元素,代表此元素已访问过,防止之后搜索时重复访问。//因为如果向下递归时,下一层递归会往上走,这样是为了防止走回头路board[i][j] = '\0';//对下一个待匹配字符进行搜索其余路径(下,上,右,左)//只要有一个返回true就不会继续往下试探了bool 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] = '\0' 来防止 ”走回头路“ 。当匹配字符串不成功时,会回溯返回,此时需要board[i][j] = word[k] 来 取消对此单元格的标记。 在DFS过程中,每个单元格会多次被访问的, board[i][j] = '\0'只是要保证在当前匹配方案中不要走回头路。
取消对board[i][j]的标记是因为只代表此次搜索过程中,该元素已访问过,
当初始i j变化时,又开始了另一次搜索过程
*/board[i][j] = word[k]; //还原当前矩阵元素,因为如果当前的节点不满足路径要求,需要撤回到上一个节点,然而上一个节点此时已经赋值为“\0”,需要还原一下,继续探索其它路径。return res;}
};

剑指Offer 12—矩阵中的路径相关推荐

  1. 【算法】剑指 Offer 12. 矩阵中的路径

    文章目录 1.概述 2.我的算法 2.1 棋盘 2.1 开始节点 2.2 点没被访问 2.3 点是否在棋盘内 2.4 下一步 2.5 主方法 2.6 核心方法 2.7 测试类 3.leecode1 1 ...

  2. 【附可运行代码】剑指 Offer 12. 矩阵中的路径

    立志用最少的代码做最高效的表达 给定一个 m x n 二维字符网格 board 和一个字符串单词 word .如果 word 存在于网格中,返回 true :否则,返回 false . 单词必须按照字 ...

  3. 剑指 Offer 12. 矩阵中的路径

    这里使用了回溯算法,回溯算法是一种比较特别的DFS,它需要在达到搜索条件后,回溯上一次,继续搜索.普通的DFS适合找路径是否存在的问题,而回溯算法适合解决有几条路径的问题. 这里给出DFS的模板 df ...

  4. 剑指offer——12.矩阵中的路径(不熟)

    题目: 题1:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩 ...

  5. 【LeetCode笔记】79. 单词搜索 剑指 Offer 12 矩阵中的路径(Java、dfs)

    文章目录 题目描述 思路 & 代码 更新版 2.0 题目描述 一眼dfs,走四个方向即可 思路 & 代码 class Solution {boolean[][] visited;boo ...

  6. 剑指 Offer(C++版本)系列:剑指 Offer 12 矩阵中的路径

    文章目录 同步GitHub在此

  7. LeetCode-剑指 Offer 12. 矩阵中的路径

    剑指 Offer 12. 矩阵中的路径 思路一:DFS+回溯 DFS 解析: 递归参数: 当前元素在矩阵 board 中的行列索引 i 和 j ,当前目标字符在 word 中的索引 k . 终止条件: ...

  8. 《剑指offer》——矩阵中的路径

    更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~ T: 题目描述 请设计一个函数,用来判断在一个矩阵中是否 ...

  9. 剑指offer之矩阵中的路径

    题目描述: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格.如果一条路径经过了矩阵的某一格,那么 ...

最新文章

  1. 2020-2021Android中高级面试题大全
  2. C# delegate event
  3. 关于函数的调用是否加括号的问题
  4. method initializationerror not found:JUnit4单元测试报错问题
  5. EventBus设计与实现分析——事件的发布
  6. 怎样判断ios app 第一次启动
  7. Linux学习总结(二十九)系统日志
  8. Django 之 Session的简单使用
  9. 激光雷达点云的特征表达
  10. 通用横轴墨卡托投影(Universal Transvers Mercator)
  11. 用Java实现信号量机制
  12. 关于Tungsten Fabic版本问题,这一篇文章说清了
  13. pydub 音频停顿 断句 切分
  14. armbian 斐讯n1_斐讯N1安装Armbian
  15. 总说业务,到底业务常用的指标有哪些
  16. win10+黑苹果 单硬盘 双系统 超简单安装 一看就会
  17. 2021年R1快开门式压力容器操作考试及R1快开门式压力容器操作考试资料
  18. 正点原子linux驱动教程,正点原子 手把手教你学Linux之驱动开发篇
  19. 目标检测中的数据增强,包括bbox的变换
  20. 基于STC89C52RC的交通灯设计

热门文章

  1. 华为AI计算机,华为在人工智能行业的发展
  2. 东京性价比高的街区是哪里?
  3. linux 版本的选择,以及如何查看linux版本
  4. iphone计算机如何打字速度,打字速度太慢了?教你几招快速提高iPhone打字速度
  5. 使用Python3和BeautifulSoup爬取笑话网站内容,并导入Excel
  6. 视口锁定解锁lisp_求一个cad 图层锁定和解锁的lisp命令?
  7. paip VOB DVD视频的无损分割与截取
  8. Linux tar 解压缩工具
  9. 大学生使用计算机情况,大学生电脑使用情况调查报告.doc
  10. 7-51单片机ESP8266学习-AT指令(测试TCP服务器--51单片机程序配置8266,用手机TCP调试助手发信息给单片机控制小灯的亮灭)