给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
[‘A’,‘B’,‘C’,‘E’],
[‘S’,‘F’,‘C’,‘S’],
[‘A’,‘D’,‘E’,‘E’]
]
给定 word = “ABCCED”, 返回 true
给定 word = “SEE”, 返回 true
给定 word = “ABCB”, 返回 false
提示:
board 和 word 中只包含大写和小写英文字母。
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
解题思路:
这又是一道DFS应用题目,在搜索check函数中,首先看当前位置是不是你想要的字母,不是直接返回false,是的话再确认一下是不是最后一个字母,是的话直接返回true,如果不是最后一个字母,那么标记当前位置为访问过,接着开始上下左右遍历,定义一个vector<pair<int, int>>,{0,1},{0,-1},{-1,0},{1,0}代表着上下左右,for循环遍历这个vector,更新i,j,对其上下左右开始遍历,如果接受到的flag为true,返回并停止遍历,最后注意要解除标记,否则会影响别的遍历,代码如下:
class Solution {
public:
bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
//没有该字母
if (board[i][j] != s[k]) {
return false;
} else if (k == s.length() - 1) { //正好到达最后一个单词
return true;
}
visited[i][j] = true;//代表访问过
vector<pair<int, int>> directions{ { 0, 1}, { 0, -1}, { 1, 0}, { -1, 0}};//上下左右
bool result = false;
for (const auto& dir: directions) {
int newi = i + dir.first, newj = j + dir.second;
if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) { //在输入的二维网格范围内
if (!visited[newi][newj]) {
bool flag = check(board, visited, newi, newj, s, k + 1);
if (flag) {
result = true;
break;
}
}
}
}
visited[i][j] = false;//一次访问结束要取消标记
return result;
}
bool exist(vector<vector<char>>& board, string word) {
int h = board.size(), w = board[0].size();
vector<vector<int>> visited(h, vector<int>(w));//w*h的二维未标记网格
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
bool flag = check(board, visited, i, j, word, 0);
if (flag) {
return true;
}
}
}
return false;
}
};