題目描述
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、一眼看過去,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有了更深的理解,之前做題是直接應用它們,這次,還在原來熟知的版本上進行了一些更改。
同時,雖然還沒學到動態規劃,但已經使用兩次了,心裏對它有了一些瞭解。