这道题我一开始的思路是 找到matrix中比周围都小的数作为起点然后dfs。这个最大的问题是无法有效地记录已经走过的路径,导致重复计算,进而导致时间复杂度非常高。
对于一般graph dfs的问题,我们一般是走一步就改变某一格的值-记录已经走过的路径,进而时间复杂度不高。
对于这道题来说,我们可以使用一个额外的 vector(二维数组)来记录每个位置的最长路径长度,这实际上就是一种动态规划结合DFS的解法,被称为“记忆化搜索(Memoization)”。这是最优解之一,因为它通过记录已经计算过的路径长度,避免了重复计算,从而显著降低时间复杂度。我原先的思路的时间复杂度为指数级。
同时,虽然我们可以直接修改矩阵中的值,比如将数字的值改为负数,代表这里走过 并且他的depth = abs(matrix[i][j]): 我自己的小思路。尽管这种方法节省了额外的空间,但也引入了潜在的复杂性和错误风险。因为每次都需要恢复原始值,如果不小心遗漏了恢复操作,可能会导致错误的结果。所以,另外创造一个vector matrix出来是不错的选择。
class Solution {
int m, n, max_len;
vector<vector<int>> memo;
int arr1[4] = {0, 1, 0, -1}, arr2[4] = {1, 0, -1, 0};
int dfs(vector<vector<int>>& matrix, int i, int j) {
if (memo[i][j] != -1)
return memo[i][j];
int max_temp = 1;
for (int k = 0; k < 4; k++) {
int new_i = arr1[k] + i;
int new_j = arr2[k] + j;
if (0 <= new_i && new_i < m && 0 <= new_j && new_j < n &&
matrix[i][j] < matrix[new_i][new_j]) {
max_temp = max(max_temp, dfs(matrix, new_i, new_j) + 1);
}
}
memo[i][j] = max_temp;
return max_temp;
}
public:
int longestIncreasingPath(vector<vector<int>>& matrix) {
m = matrix.size(), n = matrix[0].size(), max_len = 0;
if(m == 0 || n == 0) return 0;
memo = vector<vector<int>>(m, vector<int>(n,-1)); // 这里第一次写错。
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
max_len = max(max_len, dfs(matrix, i, j));
}
}
return max_len;
}
};