[劍指 offer]--DFS+剪枝--面試題12. 矩陣中的路徑

1 題目描述

請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格子。例如,在下面的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

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

2 解題思路

本問題是典型的矩陣搜索問題,可使用 深度優先搜索(DFS)+ 剪枝 解決。

算法原理:
深度優先搜索: 可以理解爲暴力法遍歷矩陣中所有字符串可能性。DFS 通過遞歸,先朝一個方向搜到底,再回溯至上個節點,沿另一個方向搜索,以此類推。
剪枝: 在搜索中,遇到 這條路不可能和目標字符串匹配成功 的情況(例如:此矩陣元素和目標字符不同、此元素已被訪問),則應立即返回,稱之爲 可行性剪枝 。
在這裏插入圖片描述
在這裏插入圖片描述

3 解決代碼

  • 方法:DFS+剪枝《Java代碼》
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){
        //返回 false : ① 行或列索引越界 或 ② 當前矩陣元素與目標字符不同 或 ③ 當前矩陣元素已訪問過 (③ 可合併至 ② ) 。
        if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]){
            return false;
        }
        //返回 true : 字符串 word 已全部匹配,即 k = len(word) - 1 。
        if(k == board.length - 1){
            return true;
        }
        //標記當前矩陣元素: 將 board[i][j] 值暫存於變量 tmp ,並修改爲字符 '/'
        char tmp = board[i][j];
        board[i][j] = '/';
        //搜索下一單元格: 朝當前元素的 上、下、左、右 四個方向開啓下層遞歸,
        //使用 或 連接 (代表只需一條可行路徑) ,並記錄結果至 res 。
        boolean res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i, j+1,k+1) || dfs(board, word, i - 1, j, k + 1) || dfs(board, word, i, j - 1, k + 1);
        //還原當前矩陣元素: 將 tmp 暫存值還原至 board[i][j] 元素。
        board[i][j] = tmp;
        //回溯返回值: 返回 res ,代表是否搜索到目標字符串。
        return res;
    }
}
  • 方法:DFS+剪枝《python3代碼》
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
            tmp, board[i][j] = 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] = tmp
            return res
        for i in range(len(board)):
            for j in range(len(board[0])):
                if dfs(i, j , 0):return True
        return False
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章