点击关注上方“图解面试算法”,
设为“置顶或星标”,一起刷 LeetCode。
![1f6b48a4ed7638f4a5e99c6539628425.png](https://img-blog.csdnimg.cn/img_convert/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](https://img-blog.csdnimg.cn/img_convert/703e9e8801477d45f779836c73bb7af0.png)
二维矩阵在本质上你可以将其看做一个网状的图,而关于图上面的深度优先搜索,我想你应该很清楚,不论是 DFS 还是 BFS 的实现方式,最简单的就是递归,只不过对于这样一个网状图而言,我们需要将图中的每一个顶点作为起点,并根据给定的 word
都进行一次深度优先搜索,相比于图的一次遍历复杂了些,判断条件也相应的多了些,仔细结合视频动画和代码理解起来就会相当容易。
下面是示例一的一个具体解释:
![a70027733b5f23ef60aed0b421d5b963.png](https://img-blog.csdnimg.cn/img_convert/a70027733b5f23ef60aed0b421d5b963.png)
![57a7dcc531fc162dbfccb09e03f7420c.png](https://img-blog.csdnimg.cn/img_convert/57a7dcc531fc162dbfccb09e03f7420c.png)
![f6d6aebb8c317a9f4cd9539a10b9739b.png](https://img-blog.csdnimg.cn/img_convert/f6d6aebb8c317a9f4cd9539a10b9739b.png)
![449641291472574660484456f0e862f3.png](https://img-blog.csdnimg.cn/img_convert/449641291472574660484456f0e862f3.png)
![a0bd0e363a77aaefb48097811f37540c.png](https://img-blog.csdnimg.cn/img_convert/a0bd0e363a77aaefb48097811f37540c.png)
![e36aa2cceb400ce41d2358dd6c036482.png](https://img-blog.csdnimg.cn/img_convert/e36aa2cceb400ce41d2358dd6c036482.png)
![da9e9728bb69c6d4b115dd5d7e187754.png](https://img-blog.csdnimg.cn/img_convert/da9e9728bb69c6d4b115dd5d7e187754.png)
![bae8e682ce4e3646d11ad2c8a65a565f.png](https://img-blog.csdnimg.cn/img_convert/bae8e682ce4e3646d11ad2c8a65a565f.png)
![5298867af79d514cf1ee18b471c6731f.png](https://img-blog.csdnimg.cn/img_convert/5298867af79d514cf1ee18b471c6731f.png)
![4afd7c74034b022e59f61a2e7ef37548.png](https://img-blog.csdnimg.cn/img_convert/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 ,递归
---由 五分钟学算法 原班人马打造的公众号:图解面试算法,现已正式上线!接下来我们将会在该公众号上,为大家分享优质的算法解题思路,坚持每天一篇原创文章的输出,感兴趣的小伙伴可以关注一下哈!