329. 矩阵中的最长递增路径
要点:记忆化搜索
递归dfs 暴力解法
class Solution {
public int longestIncreasingPath(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0 ) return 0;
boolean[][] dp = new boolean[matrix.length][matrix[0].length]; // 记录当前节点在本次尝试是否遍历过
int min = 0;
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
min = Math.max(min,process(matrix, dp, i, j,Integer.MIN_VALUE));
}
}
return min;
}
// x y 代表当前位置 value代表上次位置的值
public int process(int[][] matrix, boolean[][] dp, int x, int y,int value){
if(x < 0 || y < 0 || matrix.length <= x || matrix[0].length <= y || dp[x][y] || matrix[x][y] <= value){
return 0;
}
dp[x][y] = true; // 标记
int cur = matrix[x][y];
int max = Math.max(
Math.max(process(matrix,dp,x+1,y,cur),process(matrix,dp,x,y+1,cur)),
Math.max(process(matrix,dp,x-1,y,cur),process(matrix,dp,x,y-1,cur))
);
dp[x][y] = false; // 去除标记
return max + 1;
}
}
记忆化
搞清楚为什么可以记忆化? 因为一个位置最大递增路径只有一条,如果符合规则,加上该递增路径,可以避免大量的重复计算
class Solution {
private final int[][] directions = {{1,0},{-1,0},{0,1},{0,-1}}; // 方便遍历
public int longestIncreasingPath(int[][] matrix) {
if(matrix.length == 0 || matrix[0].length == 0) return 0;
int max = 0;
int[][] dp = new int[matrix.length][matrix[0].length]; // 记忆化需要空间
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
max = Math.max(max,longest(matrix,dp,i,j,Integer.MIN_VALUE));
}
}
return max;
}
public int longest(int[][] matrix, int[][] dp, int x,int y, int value){
if(x < 0 || y < 0 || x >= matrix.length || y >= matrix[0].length || matrix[x][y] <= value){
return 0;
}
if(dp[x][y] != 0) return dp[x][y]; // 如果记忆过,直接返回
int max = 0;
for(int[] dirs : directions){ // 遍历各个方向
int newX = x + dirs[0];
int newY = y + dirs[1];
max = Math.max(longest(matrix,dp,newX,newY,matrix[x][y]),max);
}
dp[x][y] = max + 1;
return dp[x][y];
}
}