题目
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
思路
用回溯的思想解决,包含DFS(深度优先遍历)和状态重置(即不匹配回退到前一步位置)
java代码如下:
public class Solution {
int[][] dirs = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};
int rows;//矩形的长
int cols;//矩形的宽
int len;//word长度
boolean[][] visited;//标记数组,判断是否访问过该元素
char[] charArray;//接受字符串word转化成的字符数组
public boolean exist(char[][] board, String word) {
rows = board.length;
if (rows == 0) {
return false;
}
cols = board[0].length;
visited = new boolean[rows][cols];
len = word.length();
charArray = word.toCharArray();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (dfs(board, i, j, 0)) {
return true;
}
}
}
return false;
}
private boolean dfs(char[][] board,int x, int y, int begin) {
if (begin == len - 1) {//如果比较的就是word最后一位
return board[x][y] == charArray[begin];//就只用看一位,即看当前[x][y]是否等于begin的元素
}
if (board[x][y] == charArray[begin]) {
visited[x][y] = true;//表示[x][y]坐标元素已经访问过
for (int[] dir : dirs) {
int newX = x + dir[0];
int newY = y + dir[1];
if (inArea(newX, newY) && !visited[newX][newY]) {//如果新方向的位置(上下左右)是合法的,即在矩形内,且未被访问过
if (dfs(board,newX, newY, begin + 1)) {//继续判断矩形中新位置的元素和单词中第二个字符是否相等,如果相等返回true
return true;
}
}
}
//for循环中有return语句,没有返回成功的话,说明当前新的位置元素不匹配,所以需要回溯
visited[x][y] = false;
}
return false;
}
private boolean inArea(int x, int y) {
return x >= 0 && x < rows && y >= 0 && y < cols;
}
}