LeetCode–矩陣中的路徑
LeetCode–矩陣中的路徑
部落格說明
文章所涉及的資料來自網際網路整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯絡本人刪除,謝謝!
介紹
主站 79
題目
請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格子。例如,在下面的3×4的矩陣中包含一條字串“bfce”的路徑(路徑中的字母用加粗標出)。
[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]
但矩陣中不包含字串“abfb”的路徑,因為字串的第一個字元b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入這個格子。
示例 1:
輸入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
輸出:true
示例 2:
輸入:board = [["a","b"],["c","d"]], word = "abcd" 輸出:false
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
思路
作者:jyd
深度優先搜尋(DFS)+ 剪枝
深度優先搜尋: 可以理解為暴力法遍歷矩陣中所有字串可能性。DFS 通過遞迴,先朝一個方向搜到底,再回溯至上個節點,沿另一個方向搜尋,以此類推。
剪枝: 在搜尋中,遇到 這條路不可能和目標字串匹配成功 的情況(例如:此矩陣元素和目標字元不同、此元素已被訪問),則應立即返回,稱之為 可行性剪枝 。
步驟
遞迴引數:
當前元素在矩陣 board 中的行列索引 i 和 j ,當前目標字元在 word 中的索引 k 。
終止條件
返回 falsefalse : ① 行或列索引越界 或 ② 當前矩陣元素與目標字元不同 或 ③ 當前矩陣元素已訪問過 (③ 可合併至 ② ) 。
返回 truetrue : 字串 word 已全部匹配,即 k = len(word) - 1 。
遞推工作:
-
標記當前矩陣元素: 將 board[i][j] 值暫存於變數 tmp ,並修改為字元 '/' ,代表此元素已訪問過,防止之後搜尋時重複訪問。
-
搜尋下一單元格: 朝當前元素的 上、下、左、右 四個方向開啟下層遞迴,使用 或 連線 (代表只需一條可行路徑) ,並記錄結果至 res 。
-
還原當前矩陣元素: 將 tmp 暫存值還原至 board[i][j] 元素。
回溯返回值:
返回 res ,代表是否搜尋到目標字串。
程式碼
class Solution {
public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(dfs(board,words,i,j,0)){
return true;
}
}
}
return false;
}
boolean dfs(char[][] board, char[] word, int i, int j, int k){
if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]){
return false;
}
if(k == word.length - 1){
return true;
}
char tmp = board[i][j];
board[i][j] = '/';
boolean res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = tmp;
return res;
}
}
感謝
Leetcode