给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ] 给定 word = "ABCCED", 返回 true. 给定 word = "SEE", 返回 true. 给定 word = "ABCB", 返回 false.
思路:这道题用回溯法,但是有点复杂,相当于首先我们遍历原二维数组:
for (int row = 0; row < board.size(); row++) {
for (int column = 0; column < board[0].size(); column++) {
bool flag = false;
existCore(board, row, column, word, 0, memo,flag);
if (flag) return true;
}
}
在遍历过程中每次以当前节点(board[row][column])为中心节点进行回溯,如果当前节点的字符等于word的第一个字符word[0],那么在existCore函数中在依次遍历中心节点的上下左右四个节点,观察他们是否等于word[1],以此类推,当计数器的个数等于word.size()时,我们把引用传入的bool变量的flag赋值为true,最后返回falg即可。
这里要注意两点:
1 我们在回溯过程中为了避免来回重复查找,所以我们需要一个记忆数组memo来记录当前以中心节点回溯拓展过的点,每次回溯我们只回溯没有被访问过的节点,这里注意我们传入的记忆数组是引用,所以如果当前中心节点没有找到满足条件的字符串则需要把当前节点为中心节点回溯过的点置为0(未访问)
2当我提交代码的时候,发现测试样例有这个例子未通过board=[["a"]],word="a"。在判断是否有满足条件的字符串的时候,我们的条件是:start==word.size(),即计数器的值等于word的长度,但是计数器是从下标0开始计数的,所以这样的判断条件一定要有多余的空格字符才能满足,而测试样例中刚好满足测试样例没有冗余空间的二维数组是不可能运行到start==word.size()的,所以在回溯法中我们需要加一句如下判断:
if (word[start] == board[row][column]) {
if (start == (word.size() - 1)) {
flag = true;
return;
}
}
参考代码如下:
class Solution {
public:
void existCore(vector<vector<char>>& board, int row, int column, string &word, int start, vector<vector<bool>> &memo,bool &flag) {
if (memo[row][column]) return;
if (start == word.size()) {
flag = true;
return;
}
if (word[start] == board[row][column]) {
if (start == (word.size() - 1)) {
flag = true;
return;
}
memo[row][column] = true;
if ((row + 1) < board.size()) existCore(board, row + 1, column, word, start + 1, memo, flag);
if ((column + 1) < board[0].size()) existCore(board, row, column + 1, word, start + 1, memo, flag);
if ((row - 1) >= 0) existCore(board, row - 1, column, word, start + 1, memo, flag);
if ((column - 1) >= 0) existCore(board, row, column - 1, word, start + 1, memo, flag);
}
if (!flag) {
memo[row][column] = false;
}
}
bool exist(vector<vector<char>>& board, string word) {
if (board.empty() && word.empty()) return true;
if (board.empty() && !word.empty()) return false;
vector<vector<bool>> memo(board.size(), vector<bool>(board[0].size(), false));
for (int row = 0; row < board.size(); row++) {
for (int column = 0; column < board[0].size(); column++) {
bool flag = false;
existCore(board, row, column, word, 0, memo,flag);
if (flag) return true;
}
}
return false;
}
};