当前位置: 首页 > news >正文

一格一格“翻地毯”找单词——用深度优先搜索搞定单词搜索

一格一格“翻地毯”找单词——用深度优先搜索搞定单词搜索


一、引子:别看题简单,实则套路深

说起“单词搜索”这个题目,初学者第一眼可能会说:“哦不就是个查字母吗?”其实,真没这么简单。

LeetCode 上那道经典的 Word Search(单词搜索) 问题,表面看像是在玩字谜游戏,实际上却是 深度优先搜索(DFS)在二维矩阵上的经典应用场景

这道题最迷惑人的地方在于,它不只是判断“某个字母在不在”,而是要求你一格一格地“爬”、一步一步地“凿”,找到那条合法路径拼出目标单词。这个过程,就像一场 逐格推进的深度探索游戏,没有深度优先搜索的概念,分分钟就绕晕了。


二、题目复述:走迷宫一样的查字母游戏

题目是这么说的:

给定一个二维字符网格 board 和一个单词 word,判断该单词是否可以由网格中的字符组成。规则是

  • 字母必须按上下左右相邻的方式连接;
  • 同一个单元格中的字母 不允许重复使用

举个例子:

board = [['A','B','C','E'],['S','F','C','S'],['A','D','E','E']
]word = "ABCCED"  ➜ 返回 true
word = "SEE"     ➜ 返回 true
word = "ABCB"    ➜ 返回 false

这不是“扫一眼”就能找到的,你得挨个起点试,找路径,回头再退一步——这不就是 DFS 的操作么?


三、DFS 的核心思想:一条路走到底,走错就回头

深度优先搜索,咱打个通俗比方,就是“我不撞南墙不回头”,从一个起点开始,往一个方向猛扎下去,直到:

  • 要么走通(找到了目标单词);
  • 要么撞墙了(走不下去了),那就回头换路(回溯)。

你可以把 DFS 想象成一个人在密室里找出口,一边记着自己走过的路径,一边尝试所有方向。如果走不通,就原路返回,接着试下一个可能的方向。


四、代码详解:一行一行讲清楚 DFS 的精髓

(此处省略代码段,代码部分我会在后续提供)

这段 DFS 代码干了以下几件事:

  1. 从矩阵的每个字符出发,作为起点尝试匹配;
  2. 用递归方式依次往上下左右走;
  3. 如果当前位置字母和目标不一致,或者已经走过,立即回退;
  4. 一旦匹配到完整的单词,立即返回成功;
  5. 记得回溯:走完之后要把访问过的位置“撤销标记”,供其他路径使用。

你可以理解为一个人带着字典在地图上爬格子,每走一格都问自己:“我走的路径还能继续拼出目标单词吗?”

如果能,就继续;否则就回头,重新选择方向。


五、DFS 的几个关键技巧(也是很多人踩坑的地方)

✅ 技巧1:防止重复访问

DFS 最大的“雷区”就是你忘了做“标记”——会走死循环。常用的做法:

  • 用一个 visited 数组记录每个格子是否访问过;
  • 或者更简便:临时修改 board 中的字符,比如改成 “#”,走完之后再改回来。

这个技巧在很多题中都能用,比如扫雷、连通区域识别、数岛问题等。

✅ 技巧2:剪枝优化

有些路径显然不可能成功(比如当前字母就不对),那就立刻 return False,减少递归次数,避免“暴力全图搜索”。

这就像打怪过程中看一眼这关 boss 是不是你要的,不对就别浪费时间打了,换一条路。


六、进阶思考:单词搜索还能怎么玩?

如果你觉得这个问题已经拿捏,那咱可以玩点花的:

  1. 在网格中找多个单词:那就需要用字典树(Trie)+ DFS,LeetCode 上有更难版本;
  2. 加对角线方向:上下左右不够看?那就 8 个方向都能走;
  3. 把路径打印出来:不仅告诉你“有没有”,还得告诉你“怎么走”;
  4. 限制步数/代价:比如走一步要耗电,最多只能走10步,这就是路径约束问题。

七、现实应用场景:搜索、填字、拼图、迷宫

你可能觉得这题太“学术”,但其实它背后的思想,在很多地方都有用武之地:

  • OCR 校验路径:从图像中识别字符后,判断文字排列是否有意义;
  • 拼图/填字游戏自动解题:DFS 是经典解法;
  • 语音识别中的声调匹配路径
  • AI 迷宫路径搜索:玩《贪吃蛇》《扫雷》《我的世界》的小伙伴都懂。

深度优先搜索早就跳出了“纯算法题”的小圈子,走进了大数据搜索引擎、图神经网络、图像识别的实际项目中。


八、结语:学会 DFS,不再怕“路径问题”

很多人一听“DFS”就觉得“太递归了”、“太烧脑了”。其实,只要你换个角度看它,它就是在说:

相关文章:

  • MVP架构梳理
  • 使用Mathematica绘制Peano Curve
  • Linux 入门:操作系统进程详解
  • C++惯用法:In-Place Construction 和placement new
  • 【C++】封装unordered_set和unordered_map
  • ROS2学习笔记|C++ 实现 ROS 2 订阅与发布功能的完整流程
  • 《马小帅的Java闯关记》
  • NV228NV254固态美光颗粒NV255NV263
  • 网络编程,使用select()进行简单服务端与客户端通信
  • 用 PyTorch 轻松实现 MNIST 手写数字识别
  • 【MySQL】索引(重要)
  • [Java]Java的三个阶段
  • C++类_成员函数指针
  • vae笔记
  • 修复笔记:SkyReels-V2项目中的 from_config 警告
  • 学习黑客Linux权限
  • bc 命令
  • 31.软件时序控制方式抗干扰
  • 四年级数学知识边界总结思考-上册
  • FPGA----基于ZYNQ 7020实现EPICS通信系统
  • 新剧|《执法者们》《亲爱的仇敌》5月7日开播
  • 普京称俄中关系对维护世界稳定具有战略意义
  • 张求会谈陈寅恪的生前身后事
  • 澎湃读报丨央媒头版五四青年节集中刊文:以青春之我,赴时代之约
  • 保持高位运行,今天全国铁路预计发送旅客1800万人次
  • 德雷克海峡发生6.4级地震,震源深度10千米