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

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
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
思路:
利用回溯的方式,对整个board进行搜索,但是在搜索的时候有几个需要注意的地方:
1)开始的字母在board可能有好几个位置。
2)在查找是否有这个词的时候,需要保证board中的字母只能使用一次。

class Solution:def exist(self, board: List[List[str]], word: str) -> bool:if len(board) == 0 or len(board[0]) == 0:return Falseflag = Falseself.result = []i = []j = []for x in range(len(board)):for y in range(len(board[0])):if board[x][y] == word[0]:flag = Truei.append(x)j.append(y)if flag:count = 1s = set()for c in range(len(i)):# print("初始位置在:", i[c], j[c])s.add((i[c], j[c]))self.exist_sub(i[c], j[c], board, word, count, s)s.remove((i[c], j[c]))# print("返回的结果:", self.result)for r in range(len(self.result)):if self.result[r]:return Truereturn Falseelse:return Falsedef exist_sub(self, i, j, board, word, count, s):# 从上下左右四个方向进行搜索# print(count)# print(self.result)if count == len(word):self.result.append(True)# print(self.result)returnif i >= 1 and board[i-1][j] == word[count]:if (i-1, j) not in s:s.add((i-1, j))self.exist_sub(i-1, j, board, word, count+1, s)s.remove((i-1, j))if i+1 < len(board) and board[i+1][j] == word[count]:if (i + 1, j) not in s:s.add((i + 1, j))self.exist_sub(i+1, j, board, word, count+1, s)s.remove((i + 1, j))if j >= 1 and board[i][j-1] == word[count]:if (i, j - 1) not in s:s.add((i, j - 1))self.exist_sub(i, j-1, board, word, count+1, s)s.remove((i, j - 1))if j+1 < len(board[0]) and board[i][j+1] == word[count]:if (i, j + 1) not in s:s.add((i, j+1))self.exist_sub(i, j+1, board, word, count+1, s)s.remove((i, j+1))# print("都没找到")self.result.append(False)

思路2:
设函数 check(i,j,k) 表示判断以网格的 (i,j) 位置出发,能否搜索到单词 word[k…],其中 word[k…] 表示字符串 word 从第 kk 个字符开始的后缀子串。如果能搜索到,则返回 true,反之返回false。函数check(i,j,k) 的执行步骤如下:

如果board[i][j] !=s[k],当前字符不匹配,直接返回false。
如果当前已经访问到字符串的末尾,且对应字符依然匹配,此时直接返回true。
否则,遍历当前位置的所有相邻位置。如果从某个相邻位置出发,能够搜索到子串 word[k+1…],则返回 }true,否则返回false。
这样,我们对每一个位置 (i,j) 都调用函数 check(i,j,0) 进行检查:只要有一处返回 }true,就说明网格中能够找到相应的单词,否则说明不能找到。

为了防止重复遍历相同的位置,需要额外维护一个与 board 等大的 visited 数组,用于标识每个位置是否被访问过。每次遍历相邻位置时,需要跳过已经被访问的位置。

class Solution:def exist(self, board: List[List[str]], word: str) -> bool:directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]def check(i: int, j: int, k: int) -> bool:if board[i][j] != word[k]:return Falseif k == len(word) - 1:return Truevisited.add((i, j))result = Falsefor di, dj in directions:newi, newj = i + di, j + djif 0 <= newi < len(board) and 0 <= newj < len(board[0]):if (newi, newj) not in visited:if check(newi, newj, k + 1):result = Truebreakvisited.remove((i, j))return resulth, w = len(board), len(board[0])visited = set()for i in range(h):for j in range(w):if check(i, j, 0):return Truereturn False

复杂度:
时间复杂度:一个非常宽松的上界为O(MN⋅3 ^L
),其中 M, NM,N 为网格的长度与宽度,L 为字符串word 的长度。在每次调用函数 check 时,除了第一次可以进入 44 个分支以外,其余时间我们最多会进入 3 个分支(因为每个位置只能使用一次,所以走过来的分支没法走回去)。由于单词长为 L,故check(i,j,0) 的时间复杂度为 O(3^L),
而我们要执行 O(MN) 次检查。然而,由于剪枝的存在,我们在遇到不匹配或已访问的字符时会提前退出,终止递归流程。因此,实际的时间复杂度会远远小于 Θ(MN⋅3 ^L)。

空间复杂度:O(MN)。我们额外开辟了 O(MN) 的visited 数组,同时栈的深度最大为 O(min(L,MN))。

leetcode 79: 单词搜索相关推荐

  1. Leetcode 79. 单词搜索

    Leetcode 79. 单词搜索 1.问题分析 2.问题解决 3.总结 1.问题分析 题目链接:https://leetcode-cn.com/problems/word-search/   本质上 ...

  2. LeetCode 79 单词搜索

    LeetCode 79 单词搜索 题目链接 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水 ...

  3. Leetcode 79.单词搜索

    Time: 20190901 Type: Medium 题目描述 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻&q ...

  4. java实现英文文件单词搜索系统_Java实现 LeetCode 79 单词搜索

    79. 单词搜索 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格. ...

  5. LeetCode 79. 单词搜索【c++/java详细题解】

    目录 1.题目 2.思路 3.c++代码 4.java代码 1.题目 给定一个 m x n 二维字符网格 board和一个字符串单词 word .如果 word 存在于网格中,返回 true :否则, ...

  6. LeetCode 79. 单词搜索 | Python

    文章目录 79. 单词搜索 题目 解题思路 代码实现 实现结果 总结 79. 单词搜索 题目来源:https://leetcode-cn.com/problems/word-search 题目 给定一 ...

  7. Java实现 LeetCode 79 单词搜索

    79. 单词搜索 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格. ...

  8. LeetCode 79单词搜索80删除排序数组中的重复项Ⅱ81.搜索旋转排序数组Ⅱ

    新人公众号(求支持):bigsai 专注于Java.数据结构与算法,一起进大厂不迷路! 算法文章题解全部收录在github仓库bigsai-algorithm,求star! 关注回复进群即可加入力扣打 ...

  9. LeetCode - #79 单词搜索(Top 100)

    前言 本题为 LeetCode 前 100 高频题 我们社区陆续会将顾毅(Netflix 增长黑客,<iOS 面试之道>作者,ACE 职业健身教练.)的 Swift 算法题题解整理为文字版 ...

  10. LeetCode 79. 单词搜索(回溯DFS)

    1. 题目 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格.同一个 ...

最新文章

  1. p2v、v2v 转换-windows篇
  2. 安卓的自定义的DemoApplication 出现的问题。
  3. Xendesktop 可基于物理机及虚拟机的桌面控制交付
  4. SQL函数--- SQL FIRST()
  5. Docker中快速安装Redis
  6. 信息学奥赛一本通(1087:级数求和)
  7. DHCP通过NAP认证
  8. 学地球物理的如何搞好软件开发
  9. rfid在高速公路管理中的应用_RFID亮灯电子标签在仓储管理中的应用
  10. c语言打开文件出现分段故障,C文件I / O中的分段故障11(Segmentation Fault 11 in C File I/O)...
  11. http协议介绍及httpd特性详解
  12. 联想笔记本触摸板的开启、关闭
  13. QQ导出的txt聊天记录导入数据库方法
  14. 园区网核心交换机与出口路由器如何配置才能通信?
  15. 数据分析实战(一百零一):项目分析思路 —— 用户增长实践经验分享
  16. 我当测试总监的那几年 | 程序员有话说
  17. 湖南评副教授职称计算机,2019年职称评审,湖南省高校教师需关注这些问题!...
  18. 【UI设计】使用ps软件进行一些简单的操作
  19. 亚马逊波音767货机坠毁 三人遇难
  20. 如何让内容运营渗透产品,带动产品高速成长

热门文章

  1. 卷积网络平移不变性的探讨
  2. 数据库- 内联、左连接和右连接的区别
  3. 国产软件爆发 中国版Navicat,SQL Studio成数据库管理工具热门
  4. 漫画:我们为何结婚,又为何不忠?(完结篇)
  5. 昂首那瞬间,球已停止转动——HTML5实现3D球效果
  6. 雅思考试作文遇到不认识的单词,不要怕,这样做!
  7. Maven项目下:@WebServlet注解失效的解决方法
  8. PCL 由点云生成深度图像
  9. 海盗派测试分析:MFQPPDCS 总结1
  10. H264系列--简单的视频编码历史介绍