✍个人博客: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
。这里要注意的是不能走回头路,需要判断当前走的位置之前是否已经走过。具体步骤如下:
- 遍历每一个位置,如果有一个位置递归后可以得到目标字符串则就算成功。
- 进入递归函数,用
dis
来记录当前在目标字符串中遍历到的位置,如果当前位置的字符与矩阵中遍历到字符不同,就直接返回false
。 - 如果
dis = str.size() - 1
,说明已经匹配成功了,返回true
。 - 如果流程
2
和3
都没有被返回的话,就进行正常的递归操作,每次递归都回往上下左右四个方向走,如果满足条件就进入下一次递归操作。注意,用-1
来表示该位置已经被遍历过,并且递归完要记得恢复之前的数值。 - 只要匹配成功一次,主函数就直接返回
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;
}
};
欢迎大家在评论区交流~