劍指Offer系列(java版,詳細解析)12.矩陣中的路徑

程序員社區 2022-01-08 04:27:57 阅读数:671

offer 系列 java 解析

題目描述

劍指 Offer 12. 矩陣中的路徑

難度中等262

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

測試用例

  • 功能測試(在多行多列的矩陣中存在或者不存在路徑)
  • 邊界值測試(矩陣只有一行或者只有一列;矩陣和路徑中的所有字母都是相同的)
  • 特殊輸入測試(輸入空指針)

題目考點

  • 考察應聘者對回溯法的理解。通常在二維矩陣上找路徑這類問題都可以應用回溯法解决。
  • 考察應聘者對數組的編程能力。我們一般都把矩陣看成一個二維數組。只有對數組的特性充分了解,只有可能快速、正確得實現回溯法的代碼。

解題思路

這是一個可以用回朔法(見補充)解决的典型題。

首先,在矩陣中任選一個格子作為路徑的起點。

由於回朔法的遞歸特性,路徑可以被看成一個棧。當在矩陣中定比特了路徑中前n個字符的比特置之後,在與第n個字符對應的格子的周圍都沒有找到第n+1個字符,這個時候只要在路徑上回到第n-1個字符,重新定比特第n個字符。一直重複這個過程,直到路徑字符串上所有字符都在矩陣中找到合適的比特置。

由於路徑不能重複進入矩陣的格子,還需要定義和字符矩陣大小一樣的布爾值矩陣,用來標識路徑是否已經進入每個格子。

參考解題

/** * Author:Viper * Data:2021/3/11 * description: */public class problem12 {
 public boolean exist(char[][] board,String word){
 char[] words= word.toCharArray(); boolean res = false; for(int i=0;i<board.length;i++){
 for (int j = 0; j <board[0].length ; j++) {
 res = dfs(board,words,i,j,0); if(res==true) return res; } } return res; } private boolean dfs(char[][] board, char[] words, int i, int j, int k) {
 if(i<0 || i>=board.length || j<0 || j>=board[0].length||board[i][j]!=words[k]) return false; if(k==words.length-1) return true; board[i][j]='\0'; boolean res = dfs(board,words,i+1,j,k+1) || dfs(board,words,i-1,j,k+1) || dfs(board,words,i,j+1,k+1) || dfs(board,words,i,j-1,k+1); board[i][j]=words[k]; return res; }}

補充

回溯法:

回溯法可以看成蠻力法的昇級版,它非常適合由多個步驟組成的問題,並且每個步驟都有多個選項,當我們在某一步選擇了其中一個選項時,就進行下一步,如果下一步不行不符合條件,則回溯到之前那一步,不然則繼續選擇一個選項進行下一步,就這樣重複選擇,直至到達最終的狀態。

版权声明:本文为[程序員社區]所创,转载请带上原文链接,感谢。 https://gsmany.com/2022/01/202201080427569228.html