一、题目
二、思路
- 递归参数: 当前字符在矩阵
grid
中的行索引 i 和列索引 j ,当前目标字符(匹配的)在目标字符串 word 中的索引 k 。 - 终止条件:
- 返回 false :当前字符和目标字符不匹配,需要return false没必要继续dfs了,而这里也可以不判断位置坐标是否越界,直接写到四个dfs前也行;
- 返回 true : 当前目标字符(匹配的)在目标字符串 word 中的索引 k = len(word) - 1 ,即目标字符串 word 已全部匹配;
- 递归过程:
- 标记访问过字符(方法一):单独设置
visited
二维布尔数组,如果访问过当前位置的元素,则赋值为true
。 - 标记访问过字符(方法二): 将
grid[i][j]
修改为 ‘/’ ,代表此元素已访问过,防止之后搜索时重复访问。 - 搜索当前字符的下一单元格: 朝当前元素的 上、下、左、右 四个方向开启下层递归,并记录结果至布尔变量
flag
。
- 标记访问过字符(方法一):单独设置
- 回溯当前字符: 将
board[i][j]
元素还原至初始值 。 - 返回值: 返回布尔量
result
,代表是否搜索到目标字符串。
三、代码
class Solution {
private:
vector<pair<int,int>>directions{
{
0,1},{
0,-1},{
1,0},{
-1,0}};
public:
bool exist(vector<vector<char>>& grid, string word) {
int high = grid.size();
int width = grid[0].size();
vector<vector<int>> visited(high, vector<int>(width));
//分别从每个单词开始dfs
for(int i = 0; i < high; i++){
for(int j = 0; j < width; j++){
bool flag = dfs(grid, visited, i, j, word, 0);
if(flag){
return true;
}
}
}
return false;
}
bool dfs(vector<vector<char>>&grid,
vector<vector<int>>&visited, int i, int j,
string& word, int k){
if(grid[i][j] != word[k]){
//当前字符不匹配
return false;
}
if(k == word.length() - 1){
//当前已经访问到末尾,即完成word匹配
return true;
}
//标记访问过
visited[i][j] = true;
bool result = false;
for(auto dir: directions){
int x = i + dir.first, y = j + dir.second;
//若没有越界
if(isarea(grid, x, y)){
//若没有访问过
if(!visited[x][y]){
bool flag = dfs(grid, visited, x, y, word, k + 1);
if(flag){
result = true;
break;
}
}
}
}
//恢复原状
visited[i][j] = false;
return result;
}
bool isarea(vector<vector<char>>&grid,int x,int y){
//判断点是否在网格内
if(x>=0 && x<grid.size() && 0<=y && y<grid[0].size()){
return true;
}else{
return false;
}
}
};