题目
思路
这道题是一个很经典的回溯问题,对于一个二维数组,从第一个字符开始进行深度优先遍历,即从上下左右四个方向进行查找是否存在字符串 word。对应 java 代码如下。
public boolean exist(char[][] board, String word) {
int row = board.length, col = board[0].length;
// 从每个字符开始进行 dfs
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (dfs(board, word.toCharArray(), i, j, 0)) {
return true;
}
}
}
return false;
}
// 递归查找从 board[i][j] 出发是否能找到 word[index..] 的字符串,
// 其中 word[index..] 表示 word.substring(index, word.length())。
public boolean dfs (char[][] board, char[] word, int i, int j, int index){
// 递归出口
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != word[index] || index >= word.length) {
return false;
}
if (index == word.length - 1) {
return true;
}
board[i][j] = ' '; // 标记该位置已经访问过
boolean flag = dfs(board, word, i - 1, j, index + 1) ||
dfs(board, word, i + 1, j, index + 1) ||
dfs(board, word, i, j - 1, index + 1) ||
dfs(board, word, i, j + 1, index + 1);
// 回溯
board[i][j] = word[index];
return flag;
}
这里注意下 board[i][j] = ’ ’ 与 **board[i][j] = word[index];**这两行代码。
board[i][j] = ’ ’ 是为了避免重复访问。
例如 board = board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
因为在进行深度优先遍历时是从 上下左右 四个方向进行的,对于已经访问过的地方是不需要重复访问的,否则会出错。