题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
别人想法:
首先,在矩阵中查找和字符串第一个字符相同的矩阵元素b。然后,遍历矩阵元素b的上下左右四个字符,如果有和字符串下一个字符相同的矩阵元素f,则遍历矩阵元素f的上下左右四个字符……;如果没有和字符串下一个字符相同的矩阵元素f,则退到上一个字符,重新遍历。为了避免路径重复,需要一个辅助矩阵来记录路径。
基本思想:
0.根据给定数组,初始化一个标志位数组,初始化为false,表示未走过,true表示已经走过,不能走第二次
1.根据行数和列数,遍历数组,先找到一个与str字符串的第一个元素相匹配的矩阵元素,进入judge
2.根据i和j先确定一维数组的位置,因为给定的matrix是一个一维数组
3.确定递归终止条件:越界,当前找到的矩阵值不等于数组对应位置的值,已经走过的,这三类情况,都直接false,说明这条路不通
4.若k,就是待判定的字符串str的索引已经判断到了最后一位,此时说明是匹配成功的
5.下面就是本题的精髓,递归不断地寻找周围四个格子是否符合条件,只要有一个格子符合条件,就继续再找这个符合条件的格子的四周是否存在符合条件的格子,直到k到达末尾或者不满足递归条件就停止。
6.走到这一步,说明本次是不成功的,我们要还原一下标志位数组index处的标志位,进入下一轮的判断。
自己想法:
1、回溯法,递归调用
代码:
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if (matrix == nullptr || rows < 0 || cols < 0 || str == nullptr)
{
return false;
}
//建立一个动态数组,存储是否是走过的路径,走过是true,没走过是false
bool *visited = new bool[rows * cols];//新学到的,动态数组
memset(visited, 0, rows * cols);
int pathlength = 0;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{ //循环遍历二维数组,找到str中第一个字符,再递归判断四周符合条件的
if (gohaspath(matrix, rows, cols, row, col, str, pathlength, visited))
{
return true;
}
}
}
delete[] visited;//动态数组delete
return false;
}
bool gohaspath(char* matrix, int rows, int cols, int row, int col, char *str, int pathlength, bool *visited)
{ //终止条件,到达末尾与'\0'匹配
if (str[pathlength] == '\0')
{
return true;
}
//是否回溯标志,当str中某一个字符匹配成功,开始寻找四周的字符,看是否能够匹配,不能匹配的,
//回溯
bool ishaspath = false;
if (matrix && row >= 0 && col >= 0 && row < rows && col < cols && str && matrix[row * cols + col] == str[pathlength] && !visited[row * cols + col])//矩阵中数与str中数匹配
//并且visited为false(未走过)
{
++pathlength;//str中下一个字符
visited[row * cols + col] = true;//将此字符位置设为TRUE
//判断上下左右四个位置是否由匹配,
ishaspath = gohaspath(matrix, rows, cols, row, col + 1, str, pathlength, visited) ||
gohaspath(matrix, rows, cols, row, col - 1, str, pathlength, visited) ||
gohaspath(matrix, rows, cols, row + 1, col, str, pathlength, visited) ||
gohaspath(matrix, rows, cols, row - 1, col, str, pathlength, visited);
//如果四周没有匹配,回溯
if (!ishaspath)
{
--pathlength;
visited[row * cols + col] = false;
}
}
return ishaspath;
}
};