面试题12:矩阵中的路径
1 题目
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如在下面的3x4的矩阵中包含一条字符串"bcced"的路径(路径中的字母用斜体表示)。但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

2 思路
- 由于回溯的递归特性,路径可以被看成一个栈,当在矩阵中定位了路径中前n个字符位置后,在与第n个字符对应的格子的周围都没有找到第n+1个字符,这时候需要在路径上回溯到第n-1个字符,重新定位第n个字符
- 由于路径不能重复进入矩阵的格子,所以需要定义和字符矩阵大小相同的布尔矩阵,用来表示路径是否已经进入了每个格子。
3 代码
bool hasPath(char* matrix, int rows, int cols, char* str)
{
// 1.输入是否有效
if(matrix == NULL || rows < 1 || cols < 1 || str == NULL)
{
return false;
}
// 2. 创建同等大小的布尔数组
bool* visited = new bool[rows*cols];
memset(visited, 0, rows*cols);
// 3. 遍历数组所有元素,
int pathLength = 0;
for(int row = 0; row < rows; row++)
{
for(int col = 0; col < cols; col++)
{ // 查找第row ,col起始位置的元素是否满足条件
if(hasPathCore(matrix, rows, cols, row, col, str, pathLength, visited)){
delete[] visited;
return true;
}
}
}
delete[] visited;
return false;
}
bool hasPathCore(char* matrix, int rows, int cols, int row, int col, 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, rows, cols, row-1, col, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row+1, col, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row, col-1, str, pathLength, visited)
|| hasPathCore(matrix, rows, cols, row, col+1, str, pathLength, visited);
// 若不满足,则回退到上一个,并取消标记访问
if(!hasPath)
{
--pathLength;
visited[row*cols+col] = false;
}
}
return hasPath;
}

浙公网安备 33010602011771号