1. 程式人生 > 實用技巧 >LeetCode–矩陣中的路徑

LeetCode–矩陣中的路徑

LeetCode–矩陣中的路徑

部落格說明

文章所涉及的資料來自網際網路整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯絡本人刪除,謝謝!

介紹

劍指 Offer 12. 矩陣中的路徑

主站 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

以及勤勞的自己,個人部落格GitHub