題目來源: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
歡迎關注微信公衆號《書所集錄》