leetcode-矩阵中的路径-55

Posted 天津 唐秙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-矩阵中的路径-55相关的知识,希望对你有一定的参考价值。

题目要求
  给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
思路
  这个题和之前写的一篇扫雷的代码有点像,都是用到了深度优先搜索和剪枝解决的矩阵搜索问题,其中深度优先搜索可以理解为暴力法遍历矩阵中的所有字符串,dns通过递归,朝着一个方向搜索到底,再通过回溯至上一个节点,沿着另一个方向继续搜索,以此类推。剪枝是在这个方向的搜索中如果我遇到到了当前节点已经不满足要求,那么就不会对该节点上的4个方向进行探索而是直接返回。

dns部分的解析:
  第一步,我们先将下标越界的情况排除掉。
  第二步。然后将该节点下和word的字母不一样的返回,如果能够通过这两步,至少现在保证目前的这个节点是满足条件的。
  第三步,n是记录字符串对比的字符,如果字符串完全对比完,那么n的值会和字符串的长度-1相等,如果能到达这一步就说明字符串找到了。
  第四步,因为题目要求节点是不能重复使用的,因此,我们将访问过的节点修改为\\0,为啥会是\\0,这个是因为当我们字符串查找到结束的时候,字符串的结尾是\\0,如果我们不设置成\\0,判断第二步的节点的值的时候,我们就会直接返回false,但实际上我们已经把字符串找到了,需要返回的是第三步中的true。
  第五步,我们采用递归的方式对不同方向的上的节点进行对比和探索,返回值为bool类型,这也是为啥函数的返回类型是bool类型。
  第六步,最后别忘了把修改为\\0的值修改回来,因为从第一个节点开始进行递归查找是一种情况,从第个节点开始递归也是一种情况,后续也是,如果不修改回来,其他节点的在查找的时候,看到的二维数组中的数据就全是\\0了。

进一步优化:
  第五步中,采用递归的方式对不同方向上的节点进行探索,这部分的代码可以使用循环数组来解决。

代码实现

优化前的代码

class Solution {
public:
	bool exist(vector<vector<char>>& board, string word) {
		rows = board.size();
		cols = board[0].size();

		for (int i = 0; i < rows; i++)
		{
			for (int j = 0; j < cols; j++)
			{
				if (dns(board, word, i, j, 0))
					return true;
			}
		}
		return false;
	}
private:
	int rows, cols;
	bool dns(vector<vector<char>>& board, string word, int row, int col, int n)
	{
		if (row >= rows || row < 0 || col >= cols || col < 0 || board[row][col] != word[n])
			return false;
		if (n == word.size() - 1)
			return true;
		board[row][col] = '\\0';
		bool ret = dns(board, word, row + 1, col, n + 1) || dns(board, word, row - 1, col, n + 1) || dns(board, word, row, col - 1, n + 1) || dns(board, word, row, col + 1, n + 1);
		board[row][col] = word[n];
		return ret;
	}
};

优化后的代码

class Solution {
public:
	bool exist(vector<vector<char>>& board, string word) {
		rows = board.size();
		cols = board[0].size();

		for (int i = 0; i < rows; i++)
		{
			for (int j = 0; j < cols; j++)
			{
				if (dns(board, word, i, j, 0))
					return true;
			}
		}
		return false;
	}
private:
	int rows, cols;
	bool dns(vector<vector<char>>& board, string word, int row, int col, int n)
	{
		if (row >= rows || row < 0 || col >= cols || col < 0 || board[row][col] != word[n])
			return false;
		if (n == word.size() - 1)
			return true;
		char temp = board[row][col];
		board[row][col] = '\\0';
	
		//循环数组
		int dx[4] = { -1, 0, 1, 0 }, dy[4] = { 0, 1, 0, -1 };
		for (int q = 0; q < 4; q++)
		{
			int m = row + dx[q], w = col + dy[q];
			if (dns(board, word, m, w, n + 1))
				return true;
		}

		board[row][col] = temp;
		return false;
	}
};

以上是关于leetcode-矩阵中的路径-55的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 剑指offer 面试题12. 矩阵中的路径

LeetCode 剑指offer 面试题12. 矩阵中的路径

LeetCode 0329. 矩阵中的最长递增路径

leetcode(329)矩阵中的最大递增路径

leetcode12 矩阵中的路径 回溯算法

leetcode12 矩阵中的路径 回溯算法