最近做了乙個劍指offer上的劍指 offer 12. 矩陣中的路徑
這道題用了dfs和回溯演算法,挺有典型意義的,在這裡,列舉乙個,分析分析,加強記憶。
題目
分析請設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格仔。例如,在下面的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
這道題就是要求先在陣列中找到目標字串的第乙個字元及word[0],然後在這個元素的上下左右四個方向上中下乙個字元,為了保證每個元素只能遍歷一遍,可以將遍歷過得元素變為true,但如果一條路真的無解了,就回溯到上乙個元素上,這就需要乙個變數來記錄上乙個元素。
分析題意, 這道題需要求目標字串的路徑, 且只要找到乙個滿足條件的即可, 所以特別適合用 dfs 來做. 因為 dfs 比較方便記錄每條遍歷過的路徑, 正好可以用在這裡
所以我們可以從任意乙個字元開始, 依次比較它和目標字串當前下標對應的字元, 如果相等的話, 就可以繼續向四周遍歷, 同時字串下標加 1
直到字串下標達到字串長度, 這個時候就說明我們找到了乙個滿足要求的路徑, 直接返回 true 即可。
.而如果遍歷過程中某個字元並不匹配, 我們就不要繼續往下遍歷下去了, 因為肯定不滿足條件
外注意需要判斷某個字元是否已經訪問過, 所以我們需要額外定義乙個 visit 集合, 用於儲存已經訪問的元素行列下標: 在遞迴呼叫某個字元之前將其加入行列下標加入集合中, 呼叫結束後還要將其移除, 恢復現場, 避免這個下標之後在其他路徑中不能被用到
實現經典的 dfs, 需要額外 visit 集合, 以及當前目標字串的下標
依次遍歷矩陣的每個字元, 如果當前字元與目標字串的開頭相同, 就以它為起點進行 dfs, 如果發現一條滿足條件的路徑就直接返回 true, 否則繼續遍歷
優化visit 集合可以利用對原始矩陣的字元替換為 none 或其他不存在的字元代替, 而恢復時再將其替換回來即可, 這樣可以節省一些空間
如果某個方向已經找到路徑了, 就沒必要繼續遍歷下去, 直接返回即可, 這樣剪枝可以節省一些時間
**
/**
* @param board
* @param word
* @return
*/var
exist
=function
(board, word)}}
return
false};
//board是原陣列,word是目標陣列,i是行,j是列,vis是目標陣列的第幾個數
function
dfs(board,word,i,j,vis)
//獲取word目標的第vis個字元,初始下標為0
let curchar = word.
charat
(vis)
;//如果字元不同則返回
if(curchar !== board[i]
[j])
//如果單詞最後乙個字元匹配成功,則返回true
if(vis === word.length -1)
//如果當前字元相同,則繼續向下搜尋
let oldchar = board[i]
[j];
//遍歷過得陣列設定為true
board[i]
[j]=
true
;//四個方位遍歷找到目標數
let flag =
dfs(board,word,i+
1,j,vis+1)
||dfs
(board,word,i-
1,j,vis+1)
||dfs
(board,word,i,j+
1,vis+1)
||dfs
(board,word,i,j-
1,vis+1)
;// flag是false,代表這條路行不通,所以回溯到上一層的元素上去
board[i]
[j]= oldchar
return flag
}
/**
* @param board
* @param word
* @return
*/var
exist
=function
(board, word)
} board[x]
[y]= t;
return
false}}
;
劍指offer12 矩陣中的路徑
設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某個字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左 右 上 下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格仔。利用回溯法的思想,除矩陣邊界上的格仔外,其它格仔都有四個相鄰的格仔,當矩陣中座標為 ro...
矩陣中的路徑(劍指offer 12)
設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某個字串所有字元的路徑,路徑可以從矩陣中任意一格開始,每一步可以在矩陣中向左 右 上 下各移動一格,如果一條路徑經過了矩陣中的某一格,那麼該路徑不能再次進入該格仔。例下 3 x 4的矩陣中包含一條字串 bfce 的路徑,但是矩陣中不包含 abfb 路...
劍指offer 12 矩陣中的路徑
判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意乙個格仔開始,每一步可以在矩陣中向上下左右移動乙個格仔。如果一條路徑經過了矩陣中的某乙個格仔,則該路徑不能再進入該格仔。public class solution,private int rows private int c...