题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
例如:
[abcesfcsadee]\begin{bmatrix} a & b & c &e \\ s & f & c & s \\ a & d & e& e\\ \end{bmatrix}⎣⎡asabfdcceese⎦⎤矩阵中包含一条字符串“bccedbccedbcced”的路径,但是矩阵中不包含“abcbabcbabcb”路径,因为字符串的第一个字符bbb占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解题思路
- 和 机器人的运动范围 题目解题思路类似。定义一个和matrix一样大小的vector容器,初始化全部置0,每遍历一个元素,相应的vector中的位置置1。
- 在矩阵中从头到尾遍历元素,找到和字符串第一个元素匹配的元素后,进入递归程序,依次判断和该结点相邻的结点元素是否和字符串中的下一个元素匹配,如果字符串中的每个结点在矩阵中均能有路径相匹配,则返回true,否则本次匹配失败,继续遍历矩阵,找下一个与字符串中第一个结点匹配的位置,直到遍历完成矩阵中的所有结点。
- 每次匹配结束后,注意vector容器中所有为1的元素均要重新置零。
- 主函数中的参数
char *matrix
中的matrix是指向字符串的字符串指针,字符串不存在二维情况,所以matrix[i][j]
这样写是错误的,应该是matrix[i * cols + j]
才是。
代码实现
class Solution {
public:
bool IsPath(char* matrix, vector<int> &ivec,
int i, int j, int rows, int cols, char* str)
{
if(i < 0 or i >= rows or j < 0 or j >= cols)
return false;
if(matrix[i * cols + j] == *str and ivec[i * cols + j] == 0)
{
ivec[i * cols + j] = 1;
if(*(str + 1) == '\0')
return true;
return IsPath(matrix, ivec, i, j + 1, rows, cols, str + 1) or
IsPath(matrix, ivec, i + 1, j, rows, cols, str + 1) or
IsPath(matrix, ivec, i, j - 1, rows, cols, str + 1) or
IsPath(matrix, ivec, i - 1, j, rows, cols, str + 1);
}
return false; // 注意不合题意的要返回false。
}
void transferToZero(vector<int> &ivec)
{
vector<int>::iterator iter = ivec.begin();
while((iter = find(ivec.begin(), ivec.end(), 1)) != ivec.end())
*iter = 0;
}
bool hasPath(char* matrix, int rows, int cols, char* str)
{
vector<int> ivec(rows * cols, 0);
int i = 0, j = 0;
for(; i < rows; i++)
for(j = 0; j < cols; j++)
if(IsPath(matrix, ivec, i, j, rows, cols, str))
return true;
else
transferToZero(ivec);
return false;
}
};