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有了更深的理解,之前做題是直接應用它們,這次,還在原來熟知的版本上進行了一些更改。

同時,雖然還沒學到動態規劃,但已經使用兩次了,心裏對它有了一些瞭解。





發佈了37 篇原創文章 · 獲贊 0 · 訪問量 7022
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章