劍指 Offer 12 矩陣中的路徑(DFS)1

2021-10-10 09:36:42 字數 1982 閱讀 6116

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

1 <= board.length <= 200

1 <= board[i].length <= 200

演算法原理:

深度優先搜尋: 可以理解為暴力法遍歷矩陣中所有字串可能性。dfs 通過遞迴,先朝乙個方向搜到底,再回溯至上個節點,沿另乙個方向搜尋,以此類推。

剪枝: 在搜尋中,遇到 這條路不可能和目標字串匹配成功 的情況(例如:此矩陣元素和目標字元不同、此元素已被訪問),則應立即返回,稱之為 可行性剪枝 。

演算法剖析:

遞迴引數: 當前元素在矩陣 board 中的行列索引 i 和 j ,當前目標字元在 word 中的索引 k 。

終止條件:

返回 falsefalse : ① 行或列索引越界 或 ② 當前矩陣元素與目標字元不同 或 ③ 當前矩陣元素已訪問過 (③ 可合併至 ② ) 。

返回 truetrue : 字串 word 已全部匹配,即 k = len(word) - 1 。

遞推工作:

標記當前矩陣元素: 將 board[i][j] 值暫存於變數 tmp ,並修改為字元 '/' ,代表此元素已訪問過,防止之後搜尋時重複訪問。

搜尋下一單元格: 朝當前元素的 上、下、左、右 四個方向開啟下層遞迴,使用 或 連線 (代表只需一條可行路徑) ,並記錄結果至 res 。

還原當前矩陣元素: 將 tmp 暫存值還原至 board[i][j] 元素。

回溯返回值: 返回 res ,代表是否搜尋到目標字串。

**中,從每個節點 dfs 的順序為:下、上、右、左。

複雜度分析:

m,n 分別為矩陣行列大小, k為字串 word 長度。

時間複雜度 o(3^k *mn) : 最差情況下,需要遍歷矩陣中長度為 k字串的所有方案,時間複雜度為 o(3^k);矩陣中共有 mn 個起點,時間複雜度為 o(mn)。

方案數計算: 設字串長度為k,搜尋中每個字元有上、下、左、右四個方向可以選擇,捨棄回頭(上個字元)的方向,剩下 3種選擇,因此方案數的複雜度為 o(3^k) 。

空間複雜度 o(k): 搜尋過程中的遞迴深度不超過k,因此系統因函式呼叫累計使用的棧空間占用 o(k)(因為函式返回後,系統呼叫的棧空間會釋放)。最壞情況下 k =mn ,遞迴深度為 mn ,此時系統棧使用 o(mn)的額外空間。

劍指offer12 矩陣中的路徑

設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某個字串所有字元的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左 右 上 下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格仔。利用回溯法的思想,除矩陣邊界上的格仔外,其它格仔都有四個相鄰的格仔,當矩陣中座標為 ro...

矩陣中的路徑(劍指offer 12)

設計乙個函式,用來判斷在乙個矩陣中是否存在一條包含某個字串所有字元的路徑,路徑可以從矩陣中任意一格開始,每一步可以在矩陣中向左 右 上 下各移動一格,如果一條路徑經過了矩陣中的某一格,那麼該路徑不能再次進入該格仔。例下 3 x 4的矩陣中包含一條字串 bfce 的路徑,但是矩陣中不包含 abfb 路...

劍指offer 12 矩陣中的路徑

判斷在乙個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意乙個格仔開始,每一步可以在矩陣中向上下左右移動乙個格仔。如果一條路徑經過了矩陣中的某乙個格仔,則該路徑不能再進入該格仔。public class solution,private int rows private int c...