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

【回溯法】——单词搜索

79. 单词搜索

一、题目难度

中等

二、相关标签与相关企业

[相关标签]
[相关企业]

三、题目描述

给定一个 m × n m \times n m×n 二维字符网格 b o a r d board board 和一个字符串单词 w o r d word word。如果 w o r d word word 存在于网格中,返回 t r u e true true;否则,返回 f a l s e false false

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

四、示例

示例1

输入

board = [["A","B","C","E"],
         ["S","F","C","S"],
         ["A","D","E","E"]]
word = "ABCCED"

输出 t r u e true true

示例2

输入

board = [["A","B","C","E"],
         ["S","F","C","S"],
         ["A","D","E","E"]]
word = "SEE"

输出 t r u e true true

示例3

输入

board = [["A","B","C","E"],
         ["S","F","C","S"],
         ["A","D","E","E"]]
word = "ABCB"

输出 f a l s e false false

五、提示

  1. m = = b o a r d . l e n g t h m == board.length m==board.length
  2. n = b o a r d [ i ] . l e n g t h n = board[i].length n=board[i].length
  3. 1 ≤ m , n ≤ 6 1 \leq m, n \leq 6 1m,n6
  4. 1 ≤ w o r d . l e n g t h ≤ 15 1 \leq word.length \leq 15 1word.length15
  5. b o a r d board board w o r d word word 仅由大小写英文字母组成

六、进阶

你可以使用搜索剪枝的技术来优化解决方案,使其在 b o a r d board board 更大的情况下可以更快解决问题。

思路

  • 本题:
    def exist(self, board: List[List[str]], word: str) -> bool:
  • 传入网格board和目标单词word
  • 定义dfs函数用来专门寻找,输入参数当前格子位置(i,j)以及要找的单词word里对应的位置k,dfs(i, j, k)
  • return any(dfs(i, j, 0) for i in range(m) for j in range(n))对board每个位置(i, j)作为起点进行dfs,只要有一次找到了,true,结果就返回true!

dfs具体思路

  1. 检查当前格子(i, j)的字符board[i][j]与目标单词的k位置的字符word[k]是否匹配。
    • 没匹配:
      • 注意后续会进行逐层递归调用,回溯
      • 即,后面会向着四个方向全部进行dfs搜索,
      • 全都看过了,递归回来了,整个过程中一次也没有找到目标单词,没有成功return True
      • 就可以对(i,j)这个位置返回Flase了
      • 宣告从这个位置开始找是找不到的
    • 否则说明匹配
    • 匹配成功相当于往前走了一步
    • 检查走到头了吗(完全匹配)
      • k走到len(word)-1 就表示到头了
      • 返回true
    • 除此之外,(i, j )与k匹配成功但是k没到尽头!
      • 先标记当前位置(i, j)为已探索,后续dfs如果折返回到这里,会识别出已探索,或者因为无法匹配直接返回flase
    • 然后就是本题重点,对相邻的四个格子进行递归调用dfs,相当于往下个路口走
    • 遍历四个方向:for x, y in (上下左右), (。), (。), (。):
    • 不能碰壁:if 没碰壁(xy在board的范围内)
    • 调用自身递归:更新k+1 ,dfs(x, y, k+1)
      • 注意这样写是错的!!
      • 这样只是去相邻格子找了,但是没管找的结果,(没按要求返回TRUE)
      • 比如: 可能会已经找到了单词,还继续傻乎乎去相邻格子找
      • 所以:if dfs(x, y, k+1): return true才是对的
      • 调用dfs后,用if判断其返回的值,如果返回true就说明找到了,这时候任务完成!
    • 递归后,说明当前节点的所有可能都已探索!
    • 将当前位置恢复,后面从其他起点(i,j)开始找!board[i][j] = word[k]
    • 如果以上不断递归都没有找到,则return false
    • 最后对所有起点用dfs!
    • return any(dfs(i,j,k) for i in xxx for j in xxxx)
class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])

        # 定义深度优先搜索函数dfs,从给定位置(i, j)尝试匹配目标单词对应字符
        def dfs(i: int, j: int, k: int) -> bool:
            """
            深度优先搜索函数:用于在二维字符网格的特定位置尝试匹配目标单词的字符

            :param i: 当前所在行索引 
            :param j: 当前所在列索引
            :param k: 已经匹配到的目标单词中的第几个字符,用于跟踪匹配进度
            :return : 在当前位置及后续搜索中能否成功匹配整个目标单词,返回tf
            """
            # 如果当前网格位置的字符与对应单词中对应位置的字符不能匹配,直接返回f
            if board[i][j] != word[k]:
                return False
            
            # 如果已经匹配到目标单词的最后一个字符
            if k == len(word) - 1: # 说明当前搜索路径下成功匹配了整个目标单词
                return True        # 返回true

            board[i][j] = ''     # 标记当前位置(i, j)已访问

            # 遍历当前位置的所有路径(相邻的四个格子)
            for x, y in (i, j - 1), (i, j + 1), (i + 1, j), (i - 1, j):
                # 但是要确保该路径可行(没撞墙):
                if 0 <= x < m and 0 <= y < n:
                    # 递归调用dfs,继续在相邻格子中匹配目标单词的下一个字符
                    if dfs(x, y, k + 1):
                        # 如果在某个相邻各自以及后续搜索中能够匹配成功整个单词
                       return True
            #  将当前位置的字符恢复,因为之前只是为了标记临时修改了
            board[i][j] = word[k]

            # 如果对于当前位置的四个相邻格子递归搜索后仍未找到完整目标单词返回f
            return False

        return any(dfs(i, j, 0) for i in range(m) for j in range(n))



http://www.kler.cn/a/395653.html

相关文章:

  • 虎扑APP数据采集:JavaScript与AJAX的结合使用
  • MySQL技巧之跨服务器数据查询:基础篇-更新语句如何写
  • debian 系统更新升级
  • 【深度学习】学习率介绍(torch.optim.lr_scheduler学习率调度策略介绍)
  • FPGA学习(10)-数码管
  • 网络基础Linux
  • Oracle 单机及 RAC 环境 归档模式及路径修改
  • Django 2024全栈开发指南(三):数据库模型与ORM操作(上篇)
  • 搜索,CF 1666L - Labyrinth
  • ui->tableView升序
  • 自动驾驶3D目标检测综述(二)
  • 安科瑞ARD2F智能型电动机保护器在某水泥厂的应用-安科瑞黄安南
  • 京东 2025届秋招 自然语言处理
  • 为以人工智能为中心的工作负载重新设计的全局控制台
  • 如何在C#中处理必盈接口返回的股票数据?
  • 数据结构与算法:二分搜索/二分查找的python实现与相关力扣题35.搜索插入位置、74.搜索二维矩阵
  • A036-基于SpringBoot的产业园区智慧公寓管理系统
  • Transformer中的算子:其中Q,K,V就是算子
  • MySQL 5.7 源码导读
  • Leecode刷题C语言之最少翻转次数使二进制矩阵回文①
  • Excel SUMIFS
  • 无人机云台基础——CKESC电调小课堂10
  • JsonCpp
  • 【Java Web】MVC与分层开发
  • Gin路由深入
  • STM32芯片EXIT外部中断的配置与原理