LeetCode: 记忆化 题型知识点
记忆化通常用来以空间换取时间来优化算法性能。
本题是求图的最长递增路径
DFS过程:在当前位置 (x,y) 上我们需要检查上下左右四个方向是否连通,如果都不连通说明是终点,则其长度为1;如果有连通,则长度为另外几个位置的最大长度+1;
本题在单纯使用DFS的过程中会多次计算一个节点的长度,所以我们使用数组将搜索过的节点的最长递增路径保留下来,也就是记忆化的过程,这样我们每次遍历如果搜索过了则直接返回保存的答案即可。(DFS递归的搜索过程保证了后面搜索的节点并不会影响前面搜索节点获得的最长路径的准确性)
//DFS+记忆化
class Solution {
int[][] matrix;
int[][] store;
int m, n;
public int longestIncreasingPath(int[][] matrix) {
if(matrix.length==0) return 0;
this.matrix=matrix;
m = matrix.length;
n = matrix[0].length;
int res = 0;
store = new int[m][n]; //保存matrix[x][y]为起点的最长距离
for(int i = 0 ; i < m ; i++){
for(int j = 0 ; j < n ; j++){
if(store[i][j]==0) res = Math.max(res,dfs(i,j));//遍历所有节点,中途搜过的节点可以跳过,将最大值保存下来
}
}
return res;
}
public int dfs(int x, int y){
if(store[x][y]!=0) return store[x][y]; //如果搜过则直接返回
store[x][y] = 1; //没搜过则至少是1,进行初始化
//在四个方向上进行比较,进入下一个dfs后,如果搜过则会直接返回最长距离,否则递归搜索,之后会依次返回
if(x+1<m && matrix[x][y]<matrix[x+1][y]) store[x][y] = Math.max(store[x][y],dfs(x+1,y)+1);
if(x-1>=0 && matrix[x][y]<matrix[x-1][y]) store[x][y] = Math.max(store[x][y],dfs(x-1,y)+1);
if(y+1<n && matrix[x][y]<matrix[x][y+1]) store[x][y] = Math.max(store[x][y],dfs(x,y+1)+1);
if(y-1>=0 && matrix[x][y]<matrix[x][y-1]) store[x][y] = Math.max(store[x][y],dfs(x,y-1)+1);
return store[x][y];
}
}