leetcode-矩陣中的路徑
阿新 • • 發佈:2022-04-22
1. 題目描述
給定一個 m x n 二維字元網格 board 和一個字串單詞 word 。如果 word 存在於網格中,返回 true ;否則,返回 false 。
單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重複使用。
例如,在下面的 3×4 的矩陣中包含單詞 "ABCCED"(單詞中的字母已標出)
Leetcode連結:leetcode-矩陣中的路徑
示例1
輸入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 輸出:true
解題思路
本問題是典型的矩陣搜尋問題,可使用 深度優先搜尋(DFS)+ 剪枝 解決。
2. 深度優先搜尋+剪枝
- 深度優先搜尋: 可以理解為暴力法遍歷矩陣中所有字串可能性。DFS 通過遞迴,先朝一個方向搜到底,再 回溯 至上個節點,沿另一個方向搜尋,以此類推。
- 剪枝: 在搜尋中,遇到 這條路不可能和目標字串匹配成功 的情況(例如:此矩陣元素和目標字元不同、此元素已被訪問),則應立即返回,稱之為 [可行性剪枝] 。
3. DFS 解析:
遞迴引數: 當前元素在矩陣 board 中的行列索引 i 和 j ,當前目標字元在 word 中的索引 k 。
終止條件:
返回 false : (1) 行或列索引越界 (2) 當前矩陣元素與目標字元不同 (3) 當前矩陣元素已訪問 。
返回 true : k = len(word) - 1 ,即字串 word** 已全部匹配**。
遞推工作
- 標記當前矩陣元素: 將 board[i][j] 修改為 空字元 '' ,代表此元素已訪問過,防止之後搜尋時重複訪問。
- 搜尋下一單元格: 朝當前元素的 上、下、左、右 四個方向開啟下層遞迴,使用 或 連線 (代表只需找到一條可行路徑就直接返回,不再做後續 DFS ),並記錄結果至 res 。
- 還原當前矩陣元素: 將 board[i][j] 元素還原至初始值,即 word[k] 。
返回值: 返回布林量 res ,代表是否搜尋到目標字串。
4. 程式碼實現
class Solution: def exist(self, board: List[List[str]], word: str) -> bool: def dfs(i, j, k): # 終止條件:遇到邊界,字母不匹配,當前元素已訪問過 if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return False if k == len(word) - 1: return True # 置空,防止重複訪問 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] = word[k] return res for i in range(len(board)): for j in range(len(board[0])): if dfs(i, j, 0): return True return False