Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
For example,
Given board =[ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ]word =
"ABCCED"
, -> returnstrue
,
word ="SEE"
, -> returnstrue
,
word ="ABCB"
, -> returnsfalse
.
题目大意:给定一个二维数组board和一个字符串word,确定二维数组中相邻(上下左右)且不重复位置能否构成这个字符串。
思路:设置一个访问路径数组visited记录走过的路径,先找到字符串第一个字符在数组中的位置,然后检查它上下左右位置上的元素是否与字符串第二个字符相同,如果有相同的就递归检查该位置的上下左右是否有与字符串第三个字符相同的,直到word遍历结束或者都不符合条件。
Java代码:
public class Solution {
public boolean exist(char[][] board, String word) {
int row = board.length;
int col = board[0].length;
//设置访问路径数组,防止重复遍历已经走过的路径
boolean[][] visited = new boolean[row][col];
//把要查找的字符串转化为字符数组,方便操作
char[] charOfWord = word.toCharArray();
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
//先找到字符串的第一个字符
if (board[i][j] == charOfWord[0]) {
visited[i][j] = true;
//递归遍历它上下左右位置上的字符
boolean top = check(i-1, j, board
, visited, charOfWord, 1);
boolean bottom = check(i+1, j, board
, visited, charOfWord, 1);
boolean left = check(i, j-1, board
, visited, charOfWord, 1);
boolean right = check(i, j+1, board
, visited, charOfWord, 1);
//如果上下左右位置上存在一个与word一模一样的字符串就说明找到了
if (top || bottom || left || right) {
return true;
}else {
//否则一定要记着把这个位置的访问数组设置成false,
//以防后面的操作不会错误
visited[i][j] = false;
}
}
}
}
return false;
}
/**
* 用来递归检查某位置上下左右元素是否跟给定的字符相同的函数。
* 如果相同,递归检查相同位置的上下左右元素
* 否则返回false
* @param r 要检查的位置的行号
* @param c 要检查的位置的列号
* @param board 给定的二维数组
* @param visited 访问路径数组
* @param charOfWord 给定字符串的字符数组
* @param index 当前检查到charOfWord数组中第几个元素
* @return
*/
private boolean check(int r, int c, char[][] board
, boolean[][] visited, char[] charOfWord, int index){
//如果检查到了给定字符串的结尾,说明找到了目标字符串
if (index >= charOfWord.length) {
return true;
}
int row = board.length;
int col = board[0].length;
//如果到了数组边界,则这条路走不通了。
if (r < 0 || r >= row || c < 0 || c >= col) {
return false;
}
//如果当前没有访问过并且又相同,则设置当前已访问并递归检查该位置的上下左右是否合法
if ((!visited[r][ c]) && board[r][ c] == charOfWord[index]) {
visited[r][ c] = true;
boolean top = check(r-1, c, board, visited
, charOfWord, index+1);
boolean bottom = check(r+1, c, board, visited
, charOfWord, index+1);
boolean left = check(r, c-1, board, visited
, charOfWord, index+1);
boolean right = check(r, c+1, board, visited
, charOfWord, index+1);
//如果存在一个方向找到目标字符串
if (top || bottom || left || right) {
return true;
}
else {
//如果四个方向都没找到,记得把当前位置设置成未访问
visited[r][ c] = false;
return false;
}
}else {//当前位置不合法直接返回false
return false;
}
}
}