矩陣中的路徑
題目描述:
請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那么該路徑不能再次進入該格子。例如,在下面的3×4的矩陣中包含一條字符串“bfce”的路徑(路徑中的字母用加粗標出)。
[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]
但矩陣中不包含字符串“abfb”的路徑,因為字符串的第一個字符b占據了矩陣中的第一行第二個格子之后,路徑不能再次進入這個格子
解題思路
DFS + 回溯
- 常規題目,使用DFS進行遞歸求解,如果矩陣元素和當前目標字符相等,則繼續遞歸求解,這個過程同時用
visited[][]
數組記錄矩陣元素是否被訪問過,當匹配不成功或者所有可能路徑都被訪問過則失敗
class Solution {
int[][] dirs = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public boolean exist(char[][] board, String word) {
if (board == null || board[0] == null || board.length == 0 || board[0].length == 0 || word == null || word.length() == 0)
return false;
int m = board.length, n = board[0].length;
char[] chs = word.toCharArray();
boolean[][] visited = new boolean[m][n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (check(board, i, j, chs, 0, visited))
return true;
}
}
return false;
}
private boolean check(char[][] board, int row, int col, char[] chs, int idx, boolean[][] visited) {
if (row >= board.length || row < 0 || col >= board[0].length || col < 0 || chs[idx] != board[row][col] || visited[row][col] == true)
return false;
if (idx == chs.length - 1)
return true;
boolean ans = false;
visited[row][col] = true;
for (int[] dir: dirs) {
ans = ans || check(board, row + dir[0], col + dir[1], chs, idx + 1, visited);
// 一開始使用下面的 或,總報超時,因為其不發生短路,即所有情況都要計算
// ans |= check(board, row + dir[0], col + dir[1], chs, idx + 1, visited);
}
visited[row][col] = false;
return ans;
}
}
知識點
在 Java 中 短路運算符 指的是 && (與)
和 || (或)
,非短路運算符 指的是 &
和 |
- 短路運算符:顧名思義,具有短路功能
- 如果
&&
運算符的第一個表達式為false
,則第二個表達式就不會執行 - 如果
||
運算符的第一個表達式為true
, 則第二個表達式就不會執行
- 如果
- 非短路運算符
- 不管第一個表達式是否可以得出最后結果,都要對第二個表達式進行判斷