题目来源:https://leetcode-cn.com/problems/word-searchpython
给定一个二维网格和一个单词,找出该单词是否存在于网格中。数组
单词必须按照字母顺序,经过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不容许被重复使用。bash
示例:微信
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 给定 word = "ABCCED", 返回 true 给定 word = "SEE", 返回 true 给定 word = "ABCB", 返回 false
提示:优化
思路:深度优化搜索、回溯spa
首先看题意,题目中要求单词必须按照字母顺序,在给定的二维数组中,找到单词。可经过相邻单元格的字母组成,这里【相邻】包括横向和纵向相邻的单元格,这里就涉及到一个偏移量的问题,可是同一个单元的字母不可以重复使用。code
先看下如何去实现搜索?首先咱们要先要对二维数组进行遍历,要先找到跟单词首字母相同的元素,这里要注意,当找到这个元素时,要先进行标记,由于题意要求字母不能重复使用。blog
当找到这个元素时,从当前元素的位置开始进行搜索,须要往四个方位进行搜索,看看相邻的单元格元素是不是单词的下一个字母,这里分为两种状况:leetcode
当全部的字母彻底匹配时,则返回 True。rem
具体的实现代码以下。
class Solution: directions = [(1, 0), (0, -1), (-1, 0), (0, 1)] def exist(self, board: List[List[str]], word: str) -> bool: if len(board) == 0: return False # 四个方位偏移量 rows = len(board) cols = len(board[0]) # 这里用以标记元素是否使用 # False 表示未使用 # True 表示已使用 marked = [[False for _ in range(cols)] for _ in range(rows)] # 先遍历, for row in range(rows): for col in range(cols): # 当找到全部元素时返回 True if self._search(row, col, board, word, 0, marked): return True return False def _search(self, i, j, board, word, index, marked): # 终止条件 if index == len(word) - 1: return board[i][j] == word[index] # 只有匹配了才继续搜索 if board[i][j] == word[index]: # 这里先标记元素,若是搜索不成功的状况下,解除标记 marked[i][j] = True # 四个方位搜索 for dx, dy in self.directions: nrow = i + dx ncol = j + dy # 限定边界, # 搜索时找相邻未使用过的元素 if 0 <= nrow < len(board) and 0 <= ncol < len(board[0]) and not marked[nrow][ncol] and self._search(nrow, ncol, board, word, index + 1, marked): return True # 释放标记 marked[i][j] = False return False
欢迎关注微信公众号《书所集录》