轉載本文章請標明作者和出處
本文出自《愛喝純淨水的南榮牧歌》
本文題目和部分解題思路來源自《劍指offer》第二版
題目
請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格子。例如,在下面的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
解題分析
這道題,只能使用暴力DFS+剪枝來做,就是依次的遍歷二位矩陣上面的所有節點,如果和給定的單詞第一個字母匹配,那麼我們就從這個節點開始,依次看他的上下左右的節點是不是和單詞的第二個字母匹配,一旦有一個不匹配,後面的就不用比較了,直接查看二位矩陣的下一個節點,如果一直匹配到了單詞的最後一個字母都相等的話,那就是已經有匹配的了,就可以終止遍歷二位矩陣,直接返回True;如果所有節點都查看完畢,還是沒有整體匹配的,就是整個二位矩陣都沒有匹配的,返回False;
值得一提的是,不允許重複的利用節點,我們可以在判斷完當前的節點等於單詞上的某個字母之後,把這個節點的值做一個修改,等到下面的節點遍歷返回結果的時候再給修改過來;
代碼
-
java實現
class Solution { public boolean exist(char[][] board, String word) { if (Objects.isNull(board) || board.length == 0) { return false; } char[] chars = word.toCharArray(); // 依次遍歷二維矩陣的所有節點 for (int i = 0; i < board.length; i++) { for (int j = 0; j < board[0].length; j++) { if (dfs(board,chars,i,j,0)) { // 剪枝,已經找到,沒有必要再往下繼續 return true; } } } return false; } public boolean dfs(char[][] board,char[] words,int line,int row,int index) { // 剪枝 if (line >= board.length || row >= board[0].length || line < 0 || row < 0 || board[line][row] != words[index]) { return false; } // 單詞的最後一個字母也匹配上了,整體匹配完成 if (index == words.length - 1) { return true; } // 已經匹配上的字母不能重複匹配,暫時修改節點的值 char temp = board[line][row]; board[line][row] = '/'; boolean ifExist = dfs(board,words,line + 1,row,index + 1) || dfs(board,words,line - 1,row,index + 1) || dfs(board,words,line,row + 1,index + 1) || dfs(board,words,line,row - 1,index + 1); // 還原節點上的值,以免影響下面的匹配 board[line][row] = temp; // 返回這個節點開始的整體匹配結果 return ifExist; } }
-
python實現
class Solution: def exist(self, board: List[List[str]], word: str) -> bool: if board is None or len(board) == 0: return False words = list(word) for i in range(len(board)): for j in range(len(board[0])): if self.dfs(board, words, i, j, 0): return True return False def dfs(self, board, words, i, j, index): if i >= len(board) or i < 0 or j >= len(board[0]) or j < 0 or board[i][j] != words[index]: return False if index == len(words) - 1: return True temp = board[i][j] board[i][j] = "1" if_exist = self.dfs(board, words, i, j - 1, index + 1) or self.dfs(board, words, i, j + 1, index + 1) or self.dfs(board, words, i + 1, j, index + 1) or self.dfs(board, words, i - 1, j, index + 1) board[i][j] = temp return if_exist