剑指offer 11. 矩阵中的路径

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:剑指offer系列题解
📝原题地址:题目地址
📣专栏定位:为找工作的小伙伴整理常考算法题解,祝大家都能成功上岸!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。

路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。

如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。

注意:

  • 输入的路径不为空;
  • 所有出现的字符均为大写英文字母;
数据范围

矩阵中元素的总个数 [0,900]。
路径字符串的总长度 [0,900]。

样例
matrix=
[
["A","B","C","E"],
["S","F","C","S"],
["A","D","E","E"]
]

str="BCCE" , return "true" 

str="ASAE" , return "false"

方法一:DFS O(n23k)

这道题直接深搜,遍历每一个位置,只要有一个位置可以成功就返回 true 。这里要注意的是不能走回头路,需要判断当前走的位置之前是否已经走过。具体步骤如下:

  1. 遍历每一个位置,如果有一个位置递归后可以得到目标字符串则就算成功。
  2. 进入递归函数,用 dis 来记录当前在目标字符串中遍历到的位置,如果当前位置的字符与矩阵中遍历到字符不同,就直接返回 false
  3. 如果 dis = str.size() - 1 ,说明已经匹配成功了,返回 true
  4. 如果流程 23 都没有被返回的话,就进行正常的递归操作,每次递归都回往上下左右四个方向走,如果满足条件就进入下一次递归操作。注意,用 -1 来表示该位置已经被遍历过,并且递归完要记得恢复之前的数值。
  5. 只要匹配成功一次,主函数就直接返回 true
class Solution {
public:
    int n, m;
    int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
    bool dfs(vector<vector<char>>& matrix, int x, int y, int dis, string str) {
	    //如果不相等,直接返回false
        if (matrix[x][y] != str[dis])  return false;
        //判断字符串指针是否已经走到最后	
        if (dis == str.size() - 1)   return true;	
        
        char c = matrix[x][y];	//备份数组元素
        matrix[x][y] = -1;	//标记当前位置已经走过
        for (int i = 0; i < 4; i++) {
            int mx = x + dx[i], my = y + dy[i];
            //如果不满足要求则直接跳过接下来的步骤
            if (mx < 0 || mx >= n || my < 0 || my >= m || matrix[mx][my] == -1)    continue;
            if (dfs(matrix, mx, my, dis + 1, str)) return true;
        }
        matrix[x][y] = c;	//恢复数组元素
        return false;
    }
    bool hasPath(vector<vector<char>>& matrix, string& str) {
        if (matrix.size() == 0 || matrix[0].size() == 0)   return false;
        n = matrix.size(), m = matrix[0].size();
        
        //遍历每一个位置
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (dfs(matrix, i, j, 0, str))
                    return true;
                    
        return false;
    }
};

欢迎大家在评论区交流~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值