面试题12:矩阵中的路径

// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H

解题思路:

这是一个可以用回溯算法解决的问题。

首先任选一个格子开始走,如果第i次选择的这个格子的字符,恰好对应目标字符串第i个字符,

可以从这个格子的上下左右开始尝试寻找第i+1个字符,找到符合条件的继续往下走,否则就回退上一步。

(边边角角的就没有四个格子,相邻的只有2个或者3个,需要注意判断)

那么什么时候截止呢?当目标字符串的字符为'\0'就说明找到了一条路,函数就可以返回了。

由于题目的要求,进入一个格子后无法再次进入,所以应该有一个bool类型的数组记录已经组走过的路径。

伪代码:

 

bool hasPath(){
    if(参数无效)
        return false;
    
    for(每行每列每个格子){
        if(存在一条合法路径)
            return true;
    }

    return false;
}
bool hasPathCore(){
    if(当前要寻找字符的是'\0')
        return true;

    if(行列合法&&格子当前字符==目标字符&&当前格子还未进入){
        标记此格子已进入;
        字符向后移位;
        if(上下左右没有条路可以走通){
            字符向前回退;
            标记此格子未进入;
        }
    }

    return;
}

c/c++:

bool hasPath(const char* matrix, int rows, int cols, const char* str) {
	//校验参数有效性
	if (matrix == nullptr || rows < 1 || cols < 1 || str == nullptr)
		return false;

	//标记格子是否被选中,初始化为false
	bool* visited = new bool[rows*cols];
	memset(visited, 0, rows*cols);

	//从第0步,0行0列的格子开始走
	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))
				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 && !visited[cols*row + col]
		&& matrix[row*cols + col] == str[pathLength]) {
		//假设此路走得通,下一步
          //标记此格子已经被选中 ++pathLength; visited[row*cols + col] = true; //从此格子开始向上下左右寻找可行路径 hasPath = hasPathCore(matrix, rows, cols, row, col - 1, str, pathLength, visited) || hasPathCore(matrix, rows, cols, row, col + 1, str, pathLength, visited) || hasPathCore(matrix, rows, cols, row - 1, col, str, pathLength, visited) || hasPathCore(matrix, rows, cols, row + 1, col, str, pathLength, visited); //此路不通,回退
          //标记此格子未被选中 if (!hasPath) { --pathLength; visited[row*cols + col] = false; } } return hasPath; }

参考资料:

posted @ 2018-08-07 20:04  朕蹲厕唱忐忑  阅读(179)  评论(0编辑  收藏  举报