面试题12:矩阵中的路径

1 题目

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

2 思路

  1. 由于回溯的递归特性,路径可以被看成一个栈,当在矩阵中定位了路径中前n个字符位置后,在与第n个字符对应的格子的周围都没有找到第n+1个字符,这时候需要在路径上回溯到第n-1个字符,重新定位第n个字符
  2. 由于路径不能重复进入矩阵的格子,所以需要定义和字符矩阵大小相同的布尔矩阵,用来表示路径是否已经进入了每个格子。

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;
}

posted @ 2021-03-29 08:54  一地斜阳  阅读(94)  评论(0)    收藏  举报