题目描述

题解
// 回溯搜索
// 特殊情况判断,如果board的行row或列col为0,直接false。
// 构建direction数组,将矩阵移动的上左下右四个方向保存起来用于搜索,
// 构建marked boolean矩阵,与board同规模,用于标记board中遍历元素是否被使用,
// 将board和word作为类变量保存,减少backtracking参数,
// 双for循环遍历board的所有位置,i遍历行数row,j遍历列数col,
// 调用backtracking回溯搜索函数,传入行数row,列数col,遍历元素索引i和j,和
// word的遍历索引index。
//
// 定义backtracking回溯搜索函数,传入行数row,列数col,遍历元素索引i和j,和
// word的遍历索引index。老样子,定义递归结束条件:如果word索引元素index到达
// 了word的末位,则返回当前遍历位字符board[i][j]是否与word当前遍历字符
// word.charAt(index)相等的布尔值。
// 之后条件判断当前遍历字符board[i][j]是否等于word当前遍历字符 word.charAt(index)
// 如果不相等返回false
// 相等的话则将marked的相应位marked[i][j]标记为true(已使用),然后for循环
// 遍历direction四个方位int[] dic,将方位的第一个元素(行坐标增量)
// 累加给i,记为x,方位dic的第二个元素(列坐标增量)累加给j,记为y。
// 则board[x][y]为根据direction方向移动后的坐标,
// 条件判断,如果0<=x<row,且0<=y<col,且marked[x][y]为false,即board[x][y]
// 没被使用过。则递归调用backtracking,传入的board遍历位置更新为x和y,
// word遍历位置index更新为index+1。如果调用结果为true,
// 则直接返回true。四个方向for循环搜索之后,将marked[i][j]位置置为false,
//
// 回到双for循环,循环之后直接返回false(如果没搜索到,则不会返回true,
// 所以返回false。
// 执行用时:93 ms, 在所有 Java 提交中击败了28.02%的用户
// 内存消耗:36.2 MB, 在所有 Java 提交中击败了98.60%的用户
class Solution {
private int[][] direction = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}}
private boolean[][] marked
private char[][] board
private String word
public boolean exist(char[][] board, String word) {
int row = board.length
int col = board[0].length
if (row == 0 || col == 0) return false
marked = new boolean[row][col]
this.board = board
this.word = word
for (int i = 0
for (int j = 0
if (backtracking(row, col, i, j, 0))
return true
}
}
return false
}
public boolean backtracking(int row, int col, int i, int j, int index) {
if (index == word.length() - 1) {
return (board[i][j] == word.charAt(index))
}
if (board[i][j] == word.charAt(index)) {
marked[i][j] = true
for (int[] dic: direction) {
int x = i + dic[0]
int y = j + dic[1]
if (0 <= x && x < row && 0 <= y && y < col && !marked[x][y]) {
if (backtracking(row, col, x, y, index + 1)) {
return true
}
}
}
marked[i][j] = false
}
return false
}
}