【剑指offer】面试题12 矩阵中的路径

1.考点

  • 考点1:试探回溯法的运用:这个方法说穿了就是迷宫寻径,被称为“蛮力法”的升级版确实不为过,主要就是在各个方向不断地向前试探,直到试探到尽头则依次回溯。这种方法没有最快的到达终点的办法,一直都是属于有哪条路就走哪条路,某种意义上和深度优先搜索算法比较接近,不过试探回溯的本质是有序的,深度优先搜索的本质是无序的。
  • 考点2:对于递归与试探回溯的联合运用:试探回溯法的中的回溯操作,往往是借助递归或者栈的方式来实现的,而这两种情况,我个人认为,递归适用于没有节点结构体的情况,这样可以将数据的灵活性发挥到最大;而有节点结构体时,使用栈可能更佳,因为在栈中存读结构体是相当适用的。

2.代码

  • 本题属于没有结构体的情况,本人尝试过使用结构体存储数据并用栈来实现回溯,但是这样做之后代码耦合性明显提升,整体的效率感觉也不太好,就不放上来了。总而言之就是对于这种题使用递归实现是相对较好的。
//1.首先尝试用递归的方式来实现试探回溯过程
//后来考虑过用栈的方式,发现用栈主要是存上一个点的状态,这种情况适合配合节点类进行使用,递归的方式想直接变成栈的方式会有些头疼
class Solution
{
public:
	bool hasPath(char* matrix, int rows, int cols, char* str)
	{
		if (matrix == NULL || rows < 1 || cols < 1 || str == NULL)
			return false;
		//二维数组的建立必须要常量,所以只能建一个一维数组,并用memset全部赋值为false
		int pathLength = 0;
		bool *isVisited = new bool[rows*cols];
		memset(isVisited, false, rows*cols);

		//由于起始点可能为任何位置,所以需要将起点遍历所有位置,由此也简化了递归流程,只需要找出四个点顺序和路径完全一样的就行
		for (int row = 0; row < rows; row++)
		{
			for (int col = 0; col < cols; col++)
			{
				if (isHasPath(matrix, rows, cols, row, col, str, pathLength, isVisited))
				{
					//delete[] isVisited;
					return true;
				}
			}
		}
		//isVisited是一个指向一个bool数组的指针,而bool值是常量,虽然它们存在堆里,但你不能去delete常量
		//delete[] isVisited;
		return false;
	}
	bool isHasPath(char* matrix, int rows, int cols, int row, int col, char* str, int pathLength, bool* isVisited)
	{
		//递归基,当找到路径的最后一位时表示查找完成
		if (str[pathLength] == '\0')
			return true;
		bool hasPath = false;
		//1.判断当前输入的节点是否满足基本条件、与当前路径节点相等条件、未被访问条件
    	if (row >= 0 && row < rows && col >= 0 && col < cols && matrix[row*cols + col] == str[pathLength] && !isVisited[row*cols + col])
		{
			//2.当满足条件后,将路径前移,当前点的访问位赋true
			++pathLength;
			isVisited[row*cols + col] = true;
			//3.从上下左右四个方向进行试探
			hasPath = isHasPath(matrix, rows, cols, row, col - 1, str, pathLength, isVisited)
				|| isHasPath(matrix, rows, cols, row - 1, col, str, pathLength, isVisited)
				|| isHasPath(matrix, rows, cols, row, col + 1, str, pathLength, isVisited)
				|| isHasPath(matrix, rows, cols, row + 1, col, str, pathLength, isVisited);
			//4.如果在当前节点的所有试探中都没有找到符合条件的点,那么就进行回溯,路径后移,访问位赋false
			if (!hasPath)
			{
				--pathLength;
				isVisited[row*cols + col] = false;
			}
		}
		return hasPath;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值