题目描述
给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false
解题思路
题意容易理解,即判断word
是否在矩阵board
中出现。以矩阵作为搜索的范围,我们应该想到图的邻接矩阵存储结构,而结合此题题意,不难判断出应该使用深度优先遍历
查找word是否出现在矩阵中。
class Solution {
//dir为边界矩阵,简化寻找当前节点相邻节点的代码
int[][] dir = {{0,1},{0,-1},{-1,0},{1,0}};
public boolean exist(char[][] board, String word) {
//visit数组用于记录当前阶段是否已访问
boolean[][] visit = new boolean[board.length][board[0].length];
char[] words = word.toCharArray();
//每个字符均可作为起始字符,因此需要遍历整个矩阵
for(int i = 0; i < board.length; i ++){
for(int j = 0; j < board[0].length; j ++){
if(dfs(board,i,j,words,0,visit)) return true;
}
}
return false;
}
//用于判断以x,y为起始字符,遍历所有未标记结点,能否找出words[index,words.length())的字符
private boolean dfs(char[][] board,int x,int y,char[] words,int index,boolean[][] visit){
//判断当前字符与words首字符是否相同
if(board[x][y] == words[index ++]){
//index与words.length相同,说明成功搜索到字符串结尾,即字符串存在于矩阵中
if(index == words.length) return true;
visit[x][y] = true; //标记当前结点,即当前结点已搜索过,防止重复遍历
for(int i = 0; i < 4; i ++){
//遍历dir矩阵,用于找寻上下左右四个结点
int newX = x + dir[i][0];
int newY = y + dir[i][1];
//当相邻结点合法、未被访问过时,继续判断words剩余部分是否出现在矩阵中
if(inArea(board,newX,newY) && !visit[newX][newY] && dfs(board,newX,newY,words,index,visit)) return true;
}
//此时已经搜索完(x,y)相邻结点,且没有找出words字符串,因此将标记撤回,以便后续遍历
visit[x][y] = false;
}
return false;
}
//判断节点是否在矩阵内,即节点横纵坐标是否越界
private boolean inArea(char[][] board,int i,int j){
return i >= 0 && i < board.length && j >= 0 &&j < board[0].length;
}
}