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).
Example 1:
nums = [ [9,9,4], [6,6,8], [2,1,1] ]
Return 4
The longest increasing path is [1, 2, 6, 9]
.
Example 2:
nums = [ [3,4,5], [3,2,6], [2,2,1] ]
Return 4
The longest increasing path is [3, 4, 5, 6]
. Moving diagonally is not allowed.
1、先用 拓扑 indegree来做。
2、中途 indegree[i * col + j] 写成了 indegree[i* row + j] ,非常不应该。
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix)
{
row = matrix.size();
if (row == 0) return 0;
col = matrix[0].size();
indegree = vector<int> (row * col, 0);
make_indegree(matrix);
ret = vector<vector<int>> (row, vector<int> (col, 1));
res = 1;
for (int i = 0 ; i < row * col; i++)
{
if (!find_1(matrix))
return res;
}
return res;
}
private:
vector<vector<int>> ret;
vector<int> indegree;
int row;
int col;
int res;
void make_indegree(vector<vector<int>>& matrix)
{
int a[4] = {0, 1, 0, -1};
int b[4] = {1, 0, -1, 0};
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
for (int k = 0; k < 4; k++)
{
if (isvaild(i + a[k], j + b[k]) && matrix[i + a[k]][j + b[k]] < matrix[i][j]) //周围比当前值小 就入度+1
indegree[i * col + j] ++;
}
}
}
}
bool find_1(vector<vector<int>>& matrix) //找到一个入度为0的,然后处理周边. 没找到返回false
{
int a[4] = {0, 1, 0, -1};
int b[4] = {1, 0, -1, 0};
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (indegree[i * col + j] == 0) //找到入度为0的, 海拔最低的
{
indegree[i * col + j] = -1;
for (int k = 0; k < 4; k++) //周围的入度变化
{
if (isvaild(i + a[k], j + b[k]) && matrix[i + a[k]][j + b[k]] > matrix[i][j])
{
indegree[(i+a[k]) * col + j + b[k]] --;
ret[i + a[k]][j + b[k]] = max(ret[i + a[k]][j + b[k]], ret[i][j] + 1);
res = max(res, ret[i + a[k]][j + b[k]]);
}
}
return true;
}
}
}
return false;
}
bool isvaild(int x, int y)
{
return x >= 0 && x < row && y >= 0 && y < col;
}
};
2、还有一个常规方法,那就是DFS。
找依次找最高点,然后往周围辐射。然后每次DFS刷新。
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix)
{
row = matrix.size();
if (row == 0) return 0;
col = matrix[0].size();
ret = vector<vector<int>> (row, vector<int> (col, 1));
res = 1;
multimap<int, pair<int, int>, greater<int> > mp;
for (int i = 0; i < row; i++)
{
for (int j = 0 ; j < col; j++)
{
mp.insert(make_pair(matrix[i][j], make_pair(i, j)));
}
}
for (auto it : mp)
{
if (ret[it.second.first][it.second.second] == 1)
helper(matrix, it.second.first, it.second.second, 1);
}
return res;
}
void helper(vector<vector<int>>& matrix, int x, int y, int step)
{
if (step > ret[x][y])
{
ret[x][y] = step;
res = max(res, step);
}
int a[4] = {0, 1, 0, -1};
int b[4] = {1, 0, -1, 0};
for (int i = 0; i < 4; i++)
{
if (isvaild(x + a[i], y + b[i]) && matrix[x + a[i]][y + b[i]] < matrix[x][y]
&& ret[x + a[i]][y + b[i]] < ret[x][y] + 1) //找周围比当前点低的点,并且当前步数大于之前遍历过这个点的步数
helper(matrix, x + a[i], y + b[i], ret[x][y] + 1);
}
}
private:
vector<vector<int>> ret;
int res;
int row;
int col;
bool isvaild(int x, int y)
{
return x >= 0 && x < row && y >= 0 && y < col;
}
};
最后用记忆化搜索做了一遍。证明记忆化搜索是最快的。
class Solution {
public:
int longestIncreasingPath(vector<vector<int>>& matrix)
{
row = matrix.size();
if (row == 0) return 0;
col = matrix[0].size();
ret = vector<vector<int>> (row, vector<int> (col, -1));
res = 1;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
helper(matrix, i, j);
}
return res;
}
int helper(vector<vector<int>>& matrix, int x, int y)
{
if (ret[x][y] != -1) //每个点只遍历一次 记忆化搜索标准写法
return ret[x][y];
int a[4] = {0, 1, 0, -1};
int b[4] = {1, 0, -1, 0};
int retnow = 1;
for (int i = 0; i < 4; i++)
{
if (isvaild(x + a[i], y + b[i]) && matrix[x + a[i]][y + b[i]] < matrix[x][y]) //找周围比当前点低的点
retnow = max(retnow, helper(matrix, x + a[i], y + b[i]) + 1);
}
ret[x][y] = retnow;
res = max(res, ret[x][y]); //记忆化搜索标准写法
return ret[x][y];
}
private:
vector<vector<int>> ret; //记忆化搜索
int res;
int row;
int col;
bool isvaild(int x, int y)
{
return x >= 0 && x < row && y >= 0 && y < col;
}
};