声明:题目、程序来自《剑指offer》,注释、分析为自己备忘,侵删
题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在一下面的3x4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路择不能再次讲入这个格子。
分析:匹配到对应的字符后继续往寻找下一个,没有找到下一个匹配的,则字符回退到上一个,并标记已经走过的路径。(回溯法)另外,如何记录已经走过的路径,保证在回退后不重复查询,递归可以不用记录,但循环的话可以设置一个同样大小的bool矩阵记录。
实现代码(来自剑指offer,里面调用了递归):
bool hasPath(char* matrix, int rows,int cols, char* str)
{
if(matrix == nullptr || rows<1 || cols<1|| str == nullptr)
return false;
bool *visited = new bool[rows*cols];//定义bool矩阵记录
memset(visited, 0, rows*cols);
int pathLength =0;//字符串指针
for(int row = 0; row<rows; row++){
for(int col = 0; col < cols; col ++){
if(hasPathCore(matrix, rows, cols, row, col, str, pathLength, visited){//
delete[] 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<rows &&col >=0 && col<cols && matrix[row*cols + col] == str[pathLength] && !visited[row*cols +col])
++pathLength;
visited[row*cols+col] = true;//已经查找过
hasPath = hasPathCore(matrix, row, cols, row, col -1, str, pathLength, visited)
||hasPathCore(matrix, row, cols, row - 1, col, str, pathLength, visited)
|| hasPathCore(matrix, row, cols, row, col +1, str, pathLength, visited)
|| hasPathCore(matrix, row, cols, row+1, col , str, pathLength, visited);//判断是否存在有相同的
if(!hasPath){
--pathLength;//回退
visited [row*cols +col] = false;//恢复初始值,没有查找过
}
return hasPath;
}