329. Longest Increasing Path in a Matrix

题目: Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

给定一个整数矩阵,找出最长的递增序列长度。对每一个单元,可以向四个方向移动:上下左右。不能对角线移动或移出边界外。

从题目上看,限定了上下左右移动,一共只有4个方向,很明显就要我们通过递归用深度优先搜索的方法来解题。

遍历矩阵,从任意一个点出发进行深搜,其相邻的点假如数值更大,长度加一,对这个相邻点继续深搜直到相邻的点没有数值更大的了就停止。

class Solution {
public:
	int longestIncreasingPath(vector<vector<int>>& matrix) {
		if (matrix.empty() || matrix[0].empty()) return 0;
		int m = matrix.size();
		int n = matrix[0].size();
		int Max = 1;
		for (int i = 0; i < m; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				int ret = dfs(matrix, m, n, i, j, paths);
				Max = max(Max, ret);
			}
		}
		return Max;
	}
	int dfs(vector<vector<int>>& matrix, int m, int n, int i, int j)
	{
		int path = 1;
		int current = matrix[i][j];
		if (i > 0 && matrix[i - 1][j] > current)
			path = max(path, dfs(matrix, m, n, i - 1, j) + 1);
		if (j > 0 && matrix[i][j - 1] > current)
			path = max(path, dfs(matrix, m, n, i, j - 1) + 1);
		if (i < m - 1 && matrix[i + 1][j] > current)
			path = max(path, dfs(matrix, m, n, i + 1, j) + 1);
		if (j < n - 1 && matrix[i][j + 1] > current)
			path = max(path, dfs(matrix, m, n, i, j + 1) + 1);
		return path;
	}
};

原本以为这样就可以通过了,但是竟然超时了。仔细思考一下,因为不同点开始的最长路径会重叠,比如从A点搜索有最长路径A->B->C->D,长度为4,那么从B点开始搜索,最长路径长度必然为3,因此从不同点开始搜索会重复搜索这些点,浪费了时间,造成超时。

算法提高速度的其中一个方法是用空间换时间,既然如此,只要加一个二维数组记录从当前点开始的最长路径,下次搜索到这个点的时候直接返回最长路径,不用再搜索一遍。比如最长路径A->B->C->D搜索完之后,B点坐标所在的二维数组值为3,下次搜索B的时候直接返回3,不用再搜索C、D点了

class Solution {
public:
	int longestIncreasingPath(vector<vector<int>>& matrix) {
		if (matrix.empty() || matrix[0].empty()) return 0;//特殊情况处理
		int m = matrix.size();
		int n = matrix[0].size();
		int Max = 1;
		vector<vector<int>> paths(m, vector<int>(n, 0));//记录最长路径的二维数组
		for (int i = 0; i < m; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				int ret = dfs(matrix, m, n, i, j, paths);//搜索每个点的最长路径,返回最大值
				Max = max(Max, ret);
			}
		}
		return Max;
	}
	int dfs(vector<vector<int>>& matrix, int m, int n, int i, int j, vector<vector<int>>& paths)
	{
		int path = 1;
		if (paths[i][j])//假如搜索过的直接返回
			return paths[i][j];
		int current = matrix[i][j];
		if (i > 0 && matrix[i - 1][j] > current)//四个方向搜索
			path = max(path, dfs(matrix, m, n, i - 1, j, paths) + 1);
		if (j > 0 && matrix[i][j - 1] > current)
			path = max(path, dfs(matrix, m, n, i, j - 1, paths) + 1);
		if (i < m - 1 && matrix[i + 1][j] > current)
			path = max(path, dfs(matrix, m, n, i + 1, j, paths) + 1);
		if (j < n - 1 && matrix[i][j + 1] > current)
			path = max(path, dfs(matrix, m, n, i, j + 1, paths) + 1);

		paths[i][j] = path;//搜索完记录最长路径
		return path;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值