题目描述
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有了更深的理解,之前做题是直接应用它们,这次,还在原来熟知的版本上进行了一些更改。
同时,虽然还没学到动态规划,但已经使用两次了,心里对它有了一些了解。