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 =
[ ["ABCE"], ["SFCS"], ["ADEE"] ]word =
"ABCCED"
, -> returns
true
,
word =
"SEE"
, -> returns
true
,
word = "ABCB"
, -> returns false
.
这题折腾了半天,大数据测试用例一直过不了。
我没使用递归实现,算法应该没有严重的效率问题。
我统计了一下,我的算法跟递归算法的计算次数是一样的,可能算法逻辑判断太多,效率差了些。
int[] currentPos;
char[][] board;
String word;
int[][] path;
boolean[][] flag;
int[] temp = new int[2];
public boolean exist(char[][] board, String word) {
this.board = board;
this.word = word;
int wordLen = this.word.length();
init();
this.path[0][0] = -1;
this.path[0][1] = -1;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if (board[i][j] != word.charAt(0)) {
continue;
}
if (word.length() == 1) {
return true;
}
if (this.path[0][0] >= 0) {
this.flag[this.path[0][0]][this.path[0][1]] = false;
}
this.path[0][0] = i;
this.path[0][1] = j;
this.flag[i][j] = true;
this.currentPos[1] = -1;
this.path[1][0] = -1;
this.path[1][1] = -1;
int index = 1;
while (index >= 1) {
this.currentPos[index]++;
int pos = this.currentPos[index];
int oldRow = this.path[index][0];
int oldColumn = this.path[index][1];
if (oldRow >= 0 && flag[oldRow][oldColumn]) {
flag[oldRow][oldColumn] = false;
}
pos = this.getNextPath(index, pos);
if (pos <= 3) {
if (index == wordLen - 1) {
return true;
}
this.currentPos[index] = pos;
int row = this.temp[0];
int column = this.temp[1];
flag[row][column] = true;
this.path[index][0] = row;
this.path[index][1] = column;
this.currentPos[index + 1] = -1;
this.path[index + 1][0] = -1;
this.path[index + 1][1] = -1;
index++;
} else {
index--;
}
}
}
}
return false;
}
void init() {
currentPos = new int[word.length()];
Arrays.fill(currentPos, -1);
int rowLen = board.length;
int columnLen = board[0].length;
this.path = new int[word.length()][2];
for (int i = 0; i < path.length; i++) {
path[i] = new int[2];
path[i][0] = -1;
path[i][1] = -1;
}
this.flag = new boolean[rowLen][columnLen];
for (int i = 0; i < flag.length; i++) {
Arrays.fill(this.flag[i], false);
}
}
int getNextPath(int index, int pos) {
char target = this.word.charAt(index);
while (pos <= 3) {
int row = this.path[index - 1][0];
int column = this.path[index - 1][1];
int newRow = -1;
int newColumn = -1;
if (pos == 0) {
//left
if (column - 1 >= 0) {
newRow = row;
newColumn = column - 1;
}
} else if (pos == 1) {
//right
if (column + 1 < this.board[0].length) {
newRow = row;
newColumn = column + 1;
}
} else if (pos == 2) {
//up
if (row - 1 >= 0) {
newRow = row - 1;
newColumn = column;
}
} else if (pos == 3) {
//down
if (row + 1 < this.board.length) {
newRow = row + 1;
newColumn = column;
}
}
if (newRow >= 0 && !flag[newRow][newColumn]
&& this.board[newRow][newColumn] == target) {
this.temp[0] = newRow;
this.temp[1] = newColumn;
return pos;
} else {
newRow = -1;
newColumn = -1;
pos++;
}
}
return pos;
}