思路一:对每个结点dfs,该结点的最长路径长度=max(能到达的结点的最长路径长度+1),由于存在重复子问题,因此可 加入 记忆化进行优化。
思路二:对从出度为0的结点开始进行逆拓扑排序,bfs的层数为最长路径长度。
思路一:记忆化dfs
具体思路:dp[i][j] = max(dp[m][n] + 1)
其中matrix[i][j] < matrix[m][n]
边界:matrix[m][n]比周边都大
class Solution {
public:
int xy[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int n, m;
unordered_map<int, int> hash;
int get(int x, int y) {return x * m + y;}
int dfs(vector<vector<int>>& matrix, int x, int y) {
if (hash.count(get(x, y))) return hash[get(x, y)];
int ans = 1;
for (int i = 0; i < 4; ++i) {
int xx = x + xy[i][0], yy = y + xy[i][1];
if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
if (matrix[xx][yy] > matrix[x][y]) ans = max(ans, dfs(matrix, xx, yy) + 1);
}
hash[get(x, y)] = ans;
return ans;
}
int longestIncreasingPath(vector<vector<int>>& matrix) {
n = matrix.size(), m = matrix[0].size();
int ans = 1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
ans = max(ans, dfs(matrix, i, j));
}
}
return ans;
}
};
思路二:从出度为0的结点开始进行逆拓扑排序
class Solution {
public:
int xy[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int n, m;
int get(int x, int y) {return x * m + y;}
int longestIncreasingPath(vector<vector<int>>& matrix) {
n = matrix.size(), m = matrix[0].size();
vector<int> chudu(n * m);
vector<vector<int>> bian(n * m);
//建图
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
//更新左边
if (j - 1 >= 0) {
if (matrix[i][j - 1] < matrix[i][j]) {
bian[get(i, j)].push_back(get(i, j - 1));
chudu[get(i, j - 1)]++;
}
if (matrix[i][j - 1] > matrix[i][j]) {
bian[get(i, j - 1)].push_back(get(i, j));
chudu[get(i, j)]++;
}
}
//更新上边
if (i - 1 >= 0) {
if (matrix[i - 1][j] < matrix[i][j]) {
bian[get(i, j)].push_back(get(i - 1, j));
chudu[get(i - 1, j)]++;
}
if (matrix[i - 1][j] > matrix[i][j]) {
bian[get(i - 1, j)].push_back(get(i, j));
chudu[get(i, j)]++;
}
}
}
}
queue<int> q;
for (int i = 0; i < n * m; ++i) {
if (!chudu[i]) q.push(i);
}
int ans = 0;
while (!q.empty()) {
ans++;
int len = q.size();
for (int i = 0; i < len; ++i) {
auto frt = q.front();
q.pop();
for (auto& a : bian[frt]) {
chudu[a]--;
if (!chudu[a]) q.push(a);
}
}
}
return ans;
}
};