1、回溯法
考虑到我们需要确保每一种可能,我们可以采用深度搜索加回溯的方法进行解决。我们定义backtracking函数,参数中startIndex记录现在查询到word第几位,x和y记录当前的位置。若是当前位置的字符不等于word[startIndex]则说明查询失败,若当前的startIndex等于word.size() - 1则表示整个word都已经被查询,可以返回true。此外我们先使用临时变量temp记录board[x][y]中的内容,临时把board[x][y]中的值赋值为”.“用于表示这个位置已经被查询过。接着通过定义两个移动动作数组dx和dy移动当前的位置到新位置a,b,若超出范围或为"."则说明均不可用,否则继续进行查询。当四个方向均不为下一位数时,表明我们需要进行回溯,我们将board[x][y]赋值为temp并返回false。
值得注意的是,为了避免超时,我们可以在使用参数时采用引用的方法,即&。这样可以避免函数在引用参数时开辟一个新空间,直接在原来数组的基础上进行操作,大大缩短了时间。
class Solution {
public:
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
bool backtracking(vector<vector<char>>& board, int startIndex, string word, int x, int y) {
if (board[x][y] != word[startIndex]) {
return false;
}
if (startIndex == word.size() - 1) {
return true;
}
char temp = board[x][y];
board[x][y] = '.';
for (int i = 0; i < 4; ++i) {
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a == board.size() || b < 0 || b == board[0].size() || board[a][b] == '.') {
continue;
}
if (backtracking(board, startIndex + 1, word, a, b)) {
return true;
}
}
board[x][y] = temp;
return false;
}
bool exist(vector<vector<char>> board, string word) {
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
if (backtracking(board, 0, word, i, j)) {
return true;
}
}
}
return false;
}
};