一、题目
力扣链接:矩阵中的路径
二、解法
- 从题目中可以看出,目的是要寻找一条路径,解决路径问题可以想到使用深度优先搜索DFS
- 根据解题模板(详见我的另一篇博客:link)确定该题的解题思路如下
解题模板:
int/void/... dfs(输入:一般为初始节点)
1、记录该节点对应的值,具体题目具体分析;
2、一般会增加一个变量记录是否搜索过该节点;
3、开始进行遍历,可能会有不同的方向(通常单独建立一个变量表示搜索方向):
搜索到下一个节点,判断该节点是否满足一定的条件(具体问题,具体分析):
满足条件,则会调用dfs函数进行递归(注意递归一定要有边界条件,来结束递归)
4、返回结果:return 某个值
1)遍历board中每个节点,并把其作为初始节点输入到dfs函数中,进行深度优先搜索,
2)在dfs函数中,我们需要输入初始节点(x, y),board和word,此外还需要输入一个与board同维度的board_checked(初始化为false) 来记录节点是否被搜索过以避免已经搜索过的节点再被遍历,最后为了判断输入的节点的值是否与word相同,还需要再输入一个k记录word的位置
3)由于dfs还是采用了递归的思想,那必须要有边界条件:如果输入节点的值不等于word[k],返回false;如果输入节点的值等于word[k]且k == word.size() - 1时,证明遍历的路径等于word的长度而且路径上的值都等于word,因此返回true;如果输入节点的值等于word[k]且k != word.size() - 1时,说明还没遍历到word的长度,还需要继续遍历下去。
4)修改board_checked的值为true表示该节点已被遍历过
5)沿不同方向遍历下一个节点,当满足新节点的位置在board内且该节点的board_checked为false时:调用dfs函数遍历新节点,k要变为k+1,并不断判断返回的值是否为true:为true表示有这样的路径,为false表示没有这样的路径
- C++代码如下:
class Solution {
public:
vector<int> dx = {1, -1, 0, 0};
vector<int> dy = {0, 0, 1, -1};
bool dfs(vector<vector<char>>& board, string& word, vector<vector<bool>>& board_checked, int x, int y, int k){
if (board[x][y] == word[k] && k == word.size() - 1){
return true;
}
if (board[x][y] != word[k]){
return false;
}
board_checked[x][y] = true;
bool res = false;
for (int p = 0; p < 4; p++){
int a = x + dx[p];
int b = y + dy[p];
if (a >= 0 && a < board.size() && b >= 0 && b < board[0].size()){
if (board_checked[a][b] == false){
bool flag = dfs(board, word, board_checked, a, b, k+1);
if (flag){
res = true;
break;
}
}
}
}
board_checked[x][y] = false;
return res;
}
bool exist(vector<vector<char>>& board, string word) {
int m = board.size();
int n = board[0].size();
vector<vector<bool>> board_checked(m, vector<bool>(n));
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
bool res = dfs(board, word, board_checked, i, j, 0);
if (res){
return true;
}
}
}
return false;
}
};
- 在我写的时候有一个易错点就是边界条件的判断上,我的错误是这样的
if (k == word.size() - 1){
return true;
}
if (board[x][y] != word[k]){
return false;
}
- 上面的写法就是没有考虑到返回true的条件不仅要求k == word.size() - 1还必须要求最后一个节点的值也要等于word[k]!!!所以改写的话:其实除了上面的写法,还有两种:
- 1)两个if语句颠倒一下:
if (board[x][y] != word[k]){
return false;
}
if (k == word.size() - 1){
return true;
}
- 2)用if-else if语句:
if (board[x][y] != word[k]){
return false;
}else if (k == word.size() - 1){
return true;
}
- 所以说,碰到多个if语句要想清楚各个语句之间的逻辑关系