题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
A B T G
C F C S
J D E H
解题思路:这题是一道经典的回溯法应用题,首先在数组中找到字符串的首字符,设它坐标是(row, col),然后再从(row, col)开始查找它的上下左右四个位置的元素,有没有哪个和字符串的第二个字符对应,如果有某个位置的元素与之对应,那就利用递归再查找这个位置的上下左右四个元素;如果没有对应,那就回溯到上一个坐标(如果上一个坐标的元素是字符串的首元素,那就重新在数组中查找其他对应字符串首元素的坐标)
< code >
int hasPath(const char* matrix, int rows, int cols, char* str)
{
if (rows < 1 || cols < 1 || str == NULL)
return 0;
int* visited = (int*)malloc(rows*cols*sizeof(int)); //数组visited标识 数组matrix中元素的访问情况
assert(visited != NULL);
memset(visited, 0, rows*cols*sizeof(int));
int PathLength = 0; //判断字符串str是否遍历完毕
int row = 0;
int col = 0;
for (row = 0; row < rows; row++)
{
for (col = 0; col < cols; col++)
{
if (hasPathCore(matrix, rows, cols, row, col, &PathLength, str, visited)) //这里传PathLength传地址
return 1;
}
}
free(visited);
visited = NULL;
return 0;
}
int hasPathCore(const char* matrix, int rows, int cols, int row, int col, int* PathLength, const char* str, int* visited)
{
if (str[*PathLength] == '\0')
return 1;
int hasPath = 0;
/*********************************************************
判断条件:①坐标必须在数组内
②数组中该坐标的元素必须和字符串中的字符相对应
③这个位置还没有被访问过
*********************************************************/
if (row >= 0 && row < rows && col >= 0 && col < cols
&& matrix[row*cols + col] == str[*PathLength]
&& visited[row*cols + col] == 0)
{
(*PathLength)++;
visited[row*cols + col] = 1; //访问过的元素进行标记
hasPath = hasPathCore(matrix, rows, cols, row, col - 1, PathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row - 1, col, PathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row, col + 1, PathLength, str, visited)
|| hasPathCore(matrix, rows, cols, row + 1, col, PathLength, str, visited);
if (!hasPath)//(row, col)的上下左右都不符合要求就退回到上一个位置 并 把visited[row*cols + col] = 0;
{
--(*PathLength);
visited[row*cols + col] = 0;
}
}
return hasPath;
}