遍历矩阵每一行穷举_剑指 offer 面试题精选图解 12. 矩阵中的路径

点击关注上方“图解面试算法”,

设为“置顶或星标”,一起刷 LeetCode。

1f6b48a4ed7638f4a5e99c6539628425.png 作者:景禹

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的 3×4 的矩阵中包含一条字符串 “bfce” 的路径(路径中的字母用加粗标出)。

[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]

但矩阵中不包含字符串  “abfb”  的路径,因为字符串的第一个字符 b 占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

示例1

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 输出:true

示例2

输入:board = [["a","b"],["c","d"]], word = "abcd" 输出:false

题目解析

题目考察的知识点就是深度优先搜索,在一个二维矩阵中判断是否存在单词 word 的一条路径,先从二维矩阵中选择一个任意一个起点,然后从该起点进行深度优先遍历。看下图就会更清晰:

703e9e8801477d45f779836c73bb7af0.png

二维矩阵在本质上你可以将其看做一个网状的图,而关于图上面的深度优先搜索,我想你应该很清楚,不论是 DFS 还是 BFS 的实现方式,最简单的就是递归,只不过对于这样一个网状图而言,我们需要将图中的每一个顶点作为起点,并根据给定的 word 都进行一次深度优先搜索,相比于图的一次遍历复杂了些,判断条件也相应的多了些,仔细结合视频动画和代码理解起来就会相当容易。

下面是示例一的一个具体解释:

4bbe2f2e66a68a0374b55f7c0a4d1fb1.png6f2bb597ff1668b70c2897d235963a99.png

a70027733b5f23ef60aed0b421d5b963.png
57a7dcc531fc162dbfccb09e03f7420c.png
f6d6aebb8c317a9f4cd9539a10b9739b.png
449641291472574660484456f0e862f3.png
a0bd0e363a77aaefb48097811f37540c.png
e36aa2cceb400ce41d2358dd6c036482.png

1dbd07817fe190a2eda07d2406fc2f9b.pngda56371ea952d6c07d4212f286932586.pngd7e09cca8dd335749ffb4f822331a56d.png

da9e9728bb69c6d4b115dd5d7e187754.png
bae8e682ce4e3646d11ad2c8a65a565f.png
5298867af79d514cf1ee18b471c6731f.png
4afd7c74034b022e59f61a2e7ef37548.png

动画描述

代码实现

bool hasPath(const char* matrix, int rows, int cols, const char* str){
    if(matrix == nullptr || rows 1 || cols 1 || str == nullptr)
        return false;

    bool *visited = new bool[rows * cols];
    memset(visited, 0, rows * cols);

    int pathLength = 0;
    for(int row = 0; row     {
        for(int col = 0; col         {
            if(hasPathCore(matrix, rows, cols, row, col, str,
                pathLength, visited))
            {
                return true;
            }
        }
    }

    delete[] visited;

    return false;
}

bool hasPathCore(const char* matrix, int rows, int cols, int row,int col, const char* str, int& pathLength, bool* visited){
    if(str[pathLength] == '\0')
        return true;

    bool hasPath = false;
    if(row >= 0 && row = 0 && col         && matrix[row * cols + col] == str[pathLength]
        && !visited[row * cols + col])
    {
        ++pathLength;
        visited[row * cols + col] = true;

        hasPath = hasPathCore(matrix, rows, cols, row, col - 1,
            str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row - 1, col,
                str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row, col + 1,
                str, pathLength, visited)
            || hasPathCore(matrix, rows, cols, row + 1, col,
                str, pathLength, visited);

        if(!hasPath)
        {
            --pathLength;
            visited[row * cols + col] = false;
        }
    }

    return hasPath;
}

时间复杂度

不论如何都要遍历二维矩阵一遍,即 ,对二维矩阵中的每一个顶点作为起点,最深的路径为 word 中单词的长度 ,所以最坏情况下的时间复杂度为 .

知识点

深度优先搜索 DFS ,递归

---由 五分钟学算法 原班人马打造的公众号:图解面试算法,现已正式上线!接下来我们将会在该公众号上,为大家分享优质的算法解题思路,坚持每天一篇原创文章的输出,感兴趣的小伙伴可以关注一下哈!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值