dfs-329. Longest Increasing Path in a Matrix[Hard]

题目描述

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).

Example 1:

nums = [
  [9,9,4],
  [6,6,8],
  [2,1,1]
]

Return 4
The longest increasing path is [1, 2, 6, 9].

找一条最长的路径(1,2,6,9)而且只能从上下左右四个方向寻找


解题思路


1、一眼看过去,dfs+回溯,并且不断更新 最长路径 的值。理解起来很简单,写起来也不难,可是,超时了!于是,在讨论区受到启发——使用dfs+动态规划(用一个二维矩阵记录下已经找到的从某个点出发的最长路径,当要访问的点已经有记录时,可以直接使用,不需要再用一次bfs,从而达到节省时间的目的)。当从任意一点的最长路径都知道之后,用一个二重循环,找出 max 返回即可。

2、上下左右四个方向的遍历:写一个相对位移的数组pos{(1,0),(0,1),(0,-1),(-1,0)},依次遍历即可。

3、注意数组越界,x == 0 || y == 0   以及  x==matrix.size() || y == matrix[0].size()。


4、我的代码和一般的dfs有点不同——并没有使用visited数组(一开始用了,后来发现是多余的)


代码如下(第一个是超时版本,第二个AC版本)


class Solution {
public:

void dfs(vector<vector<int>>& matrix, int cnt, int x, int y,  vector<pair<int,int> >&pos, int& tmp2) {
	
	for (int i = 0; i < pos.size(); i++) {
		int nextX = x + pos[i].first;
		int nextY = y + pos[i].second;

		if (nextX < 0 || nextY < 0)
			continue;
		if (nextX >= matrix.size() || nextY >= matrix[0].size())
			continue;
		if (matrix[x][y] > matrix[nextX][nextY]) {

			dfs(matrix, cnt + 1, nextX, nextY, pos, tmp2);
		}
	}

	if (cnt > tmp2)
		tmp2 = cnt;

}

    int longestIncreasingPath(vector<vector<int>>& matrix) {
	if (matrix.size() == 0)
		return 0;

	int rowCnt = matrix.size();
	int colCnt = matrix[0].size();

	vector<pair<int, int> > pos;
	pos.push_back(pair<int, int>(0, 1));
	pos.push_back(pair<int, int>(1, 0));
	pos.push_back(pair<int, int>(0, -1));
	pos.push_back(pair<int, int>(-1, 0));

	int tmp = 0;

	for (int i = 0; i < rowCnt; i++) {
		for (int j = 0; j < colCnt; j++) {
			int cnt = 1;
			dfs(matrix, cnt, i, j ,pos , tmp);

		}

	}

	//sort(cnt.begin(), cnt.end());
	return tmp;
}   

};



AC:


class Solution {
public:
int dfs(vector<vector<int> >& matrix, int x, int y, vector<pair<int,int> >&pos, vector<vector<int> >& result){
	int tmp = 1;
	// dfs all
	for (int i = 0; i < pos.size(); i++) {
		int last = 1;

		int nextX = x + pos[i].first;
		int nextY = y + pos[i].second;

		if (nextX < 0 || nextY < 0)
			continue;
		if (nextX >= matrix.size() || nextY >= matrix[0].size())
			continue;

		if (matrix[nextX][nextY] > matrix[x][y]) {
			if (result[nextX][nextY] != 0)
				last += result[nextX][nextY];
			else
				last += dfs(matrix, nextX, nextY, pos, result);
		}

		if (tmp < last)
			tmp = last;
		//
	}

	result[x][y] = tmp;
	return tmp;
}

int longestIncreasingPath(vector<vector<int>>& matrix) {
	if (matrix.size() == 0)
		return 0;

	vector<pair<int, int> > pos;
	pos.push_back(pair<int, int>(1, 0));
	pos.push_back(pair<int, int>(0, 1));
	pos.push_back(pair<int, int>(0, -1));
	pos.push_back(pair<int, int>(-1, 0));

	vector<vector<int> >result(matrix.size(), vector<int>(matrix[0].size(), 0));

	for (int i = 0; i < matrix.size(); i++) {
		for (int j = 0; j < matrix[i].size(); j++) {
			if (result[i][j] != 0)
				continue;

			dfs(matrix, i, j, pos, result);
		}
	}

	int max = 0;
	for (int i = 0; i < matrix.size(); i++) {
		for (int j = 0; j < matrix[i].size(); j++) {
			if (max < result[i][j])
				max = result[i][j];
		}
	}

	return max;
}

};


做题体会


两个版本,递归函数都有所不同,我写起来都不是很顺利,调试挺多的,可能是自己递归学得不是很好吧。

这道题和上次接水那题,让我对bfs、dfs有了更深的理解,之前做题是直接应用它们,这次,还在原来熟知的版本上进行了一些更改。

同时,虽然还没学到动态规划,但已经使用两次了,心里对它有了一些了解。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值