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

LeetCode 热题 100 79. 单词搜索

LeetCode 热题 100 | 79. 单词搜索

大家好,今天我们来解决一道经典的算法题——单词搜索。这道题在 LeetCode 上被标记为中等难度,要求判断一个字符串 word 是否存在于一个二维字符网格 board 中。单词必须通过相邻单元格内的字母构成,相邻单元格可以是水平或垂直方向的,且同一个单元格内的字母不能被重复使用。


问题描述

给定一个 m x n 的二维字符网格 board 和一个字符串 word,判断 word 是否存在于网格中。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

提示:

  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • boardword 仅由大小写英文字母组成。

解题思路

核心思想
  1. 深度优先搜索(DFS)

    • 从网格的每个单元格开始,尝试匹配单词的第一个字符。
    • 如果匹配成功,递归地搜索相邻单元格,匹配单词的下一个字符。
  2. 避免重复访问

    • 使用一个临时标记(如 '''0')将已访问的单元格标记为不可用,搜索完成后恢复其值。
  3. 剪枝优化

    • 如果当前路径无法匹配单词,立即回溯,避免无效搜索。
    • 提前检查单词中的字符是否在网格中出现足够的次数,如果不足,直接返回 false
  4. 优化搜索方向

    • 如果单词的最后一个字符在网格中出现次数较少,可以将单词反转后再搜索,减少搜索路径。

Python代码实现

class Solution:def exist(self, board, word):""":type board: List[List[str]]:type word: str:rtype: bool"""def dfs(i, j, k):# 如果超出边界或当前单元格不匹配,返回 Falseif not (0 <= i < len(board) and 0 <= j < len(board[0])) or board[i][j] != word[k]:return False# 如果匹配到单词的最后一个字符,返回 Trueif k == len(word) - 1:return True# 标记当前单元格为已访问temp, board[i][j] = board[i][j], ''# 搜索上下左右四个方向res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)# 恢复当前单元格的值board[i][j] = tempreturn res# 预剪枝:检查单词中的字符是否在网格中出现足够的次数from collections import Counterboard_chars = Counter(ch for row in board for ch in row)word_chars = Counter(word)if any(board_chars[ch] < word_chars[ch] for ch in word_chars):return False# 如果单词的最后一个字符在网格中出现次数较少,反转单词if board_chars[word[-1]] < board_chars[word[0]]:word = word[::-1]# 遍历网格的每个单元格,尝试匹配单词for i in range(len(board)):for j in range(len(board[0])):if dfs(i, j, 0):return Truereturn False

代码解析

  1. DFS 函数

    • dfs(i, j, k) 表示从网格的 (i, j) 位置开始,匹配单词的第 k 个字符。
    • 如果当前单元格超出边界或不匹配,返回 False
    • 如果匹配到单词的最后一个字符,返回 True
    • 使用临时标记避免重复访问,搜索完成后恢复单元格的值。
  2. 剪枝优化

    • 在开始搜索前,检查单词中的每个字符是否在网格中出现足够的次数。如果不足,直接返回 false
  3. 优化搜索方向

    • 如果单词的最后一个字符在网格中出现次数较少,可以将单词反转后再搜索,减少搜索路径。
  4. 遍历网格

    • 从网格的每个单元格开始,调用 dfs 函数尝试匹配单词。

复杂度分析

  • 时间复杂度:O(M × N × 4^L),其中 MN 是网格的行数和列数,L 是单词的长度。
  • 空间复杂度:O(L),递归的深度最大为单词的长度。

示例运行

示例 1
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true
示例 3
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB"
输出:false

总结

通过深度优先搜索(DFS)和剪枝优化,我们可以高效地解决单词搜索问题。这种方法在网格较大时也能快速返回结果,避免不必要的搜索。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!

关注我,获取更多算法题解和编程技巧!

相关文章:

  • Spring Cloud Stream集成RocketMQ(kafka/rabbitMQ通用)
  • 如何选择 边缘计算服务器
  • 代码随想录图论part03
  • 总结一下最近的知识盲区(个人笔记)
  • 抖音热门视频评论数追踪爬虫获取
  • C++ 项目 -- 高并发内存池
  • 数据可视化与分析
  • Elasticsearch知识汇总之ElasticSearch与OpenSearch比较
  • 第二章:langchain文本向量化(embed)搭建与详细教程-本地服务方式(下)
  • OpenGl实战笔记(3)基于qt5.15.2+mingw64+opengl实现光照变化效果
  • PyCharm 加载不了 conda 虚拟环境,不存在的
  • ChatGPT对话导出工具-轻松提取聊天记录导出至本地[特殊字符]安装指南
  • YOLO 从入门到精通学习指南
  • ai大模型学习1
  • Java面试全栈解析:Spring Boot、Kafka与Redis实战揭秘
  • 干货分享|检索增强生成技术RAG:向量化与大模型的结合
  • 使用batch脚本调用另一个batch脚本遇到的问题
  • uniapp app 端获取陀螺仪数据的实现攻略
  • 代理式AI(Agentic AI):2025年企业AI转型的催化剂
  • 分割回文串例题-区分组合回溯与最优动态规划
  • 潘功胜:央行将设立5000亿元服务消费与养老再贷款
  • 大规模空袭也门一日后,以军又对也门萨那机场发出撤离警告
  • 外交部:中方和欧洲议会决定同步全面取消对相互交往的限制
  • 从陈毅杯到小应氏杯,五一长假上海掀起围棋热
  • 2年就过气!ChatGPT催生的百万年薪岗位,大厂不愿意招了
  • 五问舆论漩涡中的“协和‘4+4’模式”:是否公平,如何合格?