79. 单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true


思路:采用深度优先和回溯的思路。是一道比较典型的回溯题。

定义了一个方向数组用于深度遍历时确定方向。

定义visited数组用于记录元素是否已经访问过。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class Solution {
private final static int[] DIRECTIONS = new int[]{-1, 0, 1, 0, -1};
private int rows;
private int cols;
private int len;
private char[][] board;
private char[] toCharArray;
private boolean[][] visited;

public boolean exist(char[][] board, String word) {
this.rows = board.length;
if (rows == 0) {
return false;
}
this.cols = board[0].length;
this.board = board;
this.len = word.length();
this.visited = new boolean[rows][cols];
this.toCharArray = word.toCharArray();

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (dfs(i, j, 0)) {
return true;
}
}
}
return false;

}

private boolean dfs(int x, int y, int begin) {
// 退出条件,遍历到最后一个字母
if (begin == len - 1) {
return toCharArray[begin] == board[x][y];
}
// 当前字母与单词对应下标的字母一致,则继续向四周搜索
if (toCharArray[begin] == board[x][y]) {
visited[x][y] = true;
// 向四周寻找
for (int i = 0; i < 4; i++) {
int newX = x + DIRECTIONS[i];
int newY = y + DIRECTIONS[i + 1];
// 新坐标在矩阵范围内并且没有访问过
if (isInArea(newX, newY) && !visited[newX][newY]) {
if (dfs(newX, newY, begin + 1)) {
return true;
}
}
}
// 回溯
visited[x][y] = false;
}
return false;
}

private boolean isInArea(int x, int y) {
return x >= 0 && x < rows && y >= 0 && y < cols;
}
}