【深度优先搜索】矩阵中的路径,中等难度,有易错点

一、题目

力扣链接:矩阵中的路径
在这里插入图片描述

二、解法

  • 从题目中可以看出,目的是要寻找一条路径,解决路径问题可以想到使用深度优先搜索DFS
  • 根据解题模板(详见我的另一篇博客:link)确定该题的解题思路如下
    解题模板:
int/void/... dfs(输入:一般为初始节点)
	1、记录该节点对应的值,具体题目具体分析;
	2、一般会增加一个变量记录是否搜索过该节点;
	3、开始进行遍历,可能会有不同的方向(通常单独建立一个变量表示搜索方向):
		搜索到下一个节点,判断该节点是否满足一定的条件(具体问题,具体分析):
			满足条件,则会调用dfs函数进行递归(注意递归一定要有边界条件,来结束递归)
	4、返回结果:return 某个值

1)遍历board中每个节点,并把其作为初始节点输入到dfs函数中,进行深度优先搜索,
2)在dfs函数中,我们需要输入初始节点(x, y)boardword,此外还需要输入一个与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语句要想清楚各个语句之间的逻辑关系
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值