解法1:记忆化+深度优先

链接:https://leetcode-cn.com/problems/longest-increasing-path-in-a-matrix/solution/javashi-xian-shen-du-you-xian-chao-ji-jian-dan-yi-/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
---先从一个格子开始找,对比它4周的格子,有没有比它小的,如果有,比如有A,B,C三个格子都比它小,那么当前格子的最大连续递增长度就是这3个格子的最大连续递增长度中的最大值+1(有点绕,多读两遍应该就可以理解了),那么A,B,C的最大长度从哪里来呢,答案肯定是递归去找,直到找到一个比它四周都小的格子,当前格子长度就定为1,至此,整个思路就缕清了,需要用一个与matrix一样大小的数组来存放每一个格子的最大递增长度

  • 时间复杂度:O(mn) 需要将整个数组遍历一遍,由于有visited记录,不会重复遍历

  • 空间复杂度:O(mn) 需要一个与matrix同样大小的数组,记录已经访问过的格子

    class Solution {
      public int solve(int[][] matrix) {
          if(matrix.length == 0){
              return 0;
          }
          //visited有两个作用:1.判断是否访问过,2.存储当前格子的最长递增长度
          int[][] visited = new int[matrix.length][matrix[0].length];
          int max = 0;
          for(int i=0; i<matrix.length; i++){
              for(int j=0; j<matrix[0].length; j++){
                  if(visited[i][j] == 0){
                      //这里先做一次比较找出max,可以避免最后再去遍历一个visited数组
                      max = Math.max(max, dfs(i, j, matrix, visited));
                  }
                  //max = Math.max(max, visited[i][j]);
    
              }
          }
          return max;
      }
      public int dfs(int i, int j, int[][] matrix, int[][] visited){
          if(i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length){
              return 0;
          }
          if(visited[i][j] > 0){
              return visited[i][j];
          }
          int max = 0;
          //这里分别去判断4周是否比当前数小,然后去递归遍历
          if(i - 1 >= 0 && matrix[i-1][j] < matrix[i][j]){
              max = Math.max(max, dfs(i-1, j, matrix, visited));
          }
          if(i + 1 < matrix.length && matrix[i+1][j] < matrix[i][j]){
              max = Math.max(max, dfs(i+1, j, matrix, visited));
          }
          if(j - 1 >= 0 && matrix[i][j-1] < matrix[i][j]){
              max = Math.max(max, dfs(i, j-1, matrix, visited));
          }
          if(j + 1 < matrix[0].length && matrix[i][j+1] < matrix[i][j]){
              max = Math.max(max, dfs(i, j+1, matrix, visited));
          }
    
          visited[i][j] = max+1;
          return max+1;
    
      }
    }

    解法2:拓扑排序+深度优先

  • 链接:https://blog.nowcoder.net/n/df0cf9a6a19a4222b0c6f0cea8db9a3d*

    import java.util.*;
    public class Solution {
       /**
        * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
        * 递增路径的最大长度
        * @param matrix int整型二维数组 描述矩阵的每个数
        * @return int整型
        */
       int[][] dp;
       int[] dirs = new int[]{0,1,0,-1,0};
       int m, n;
       public int solve (int[][] matrix) {
           // write code here
           int max = 1;
           m = matrix.length;
           n = matrix[0].length;
           dp = new int[m][n];
           for(int i = 0; i < m; i++) {
               for(int j = 0; j < n; j++) {
                   max = Math.max(max,  dfs(matrix, i, j));
               }
           }
           return max;
       }
    
       private int dfs(int[][] matrix, int x, int y) {
           if(dp[x][y] != 0) {
               return dp[x][y];
           }
    
           dp[x][y] = 1;
           for(int k = 0; k < 4; k++) {
               int nx = x + dirs[k];
               int ny = y + dirs[k+1];
               if(nx>=0 && nx<m && ny>=0 && ny<n && matrix[nx][ny] < matrix[x][y]) {
                   dp[x][y] = Math.max(dp[x][y], 1+dfs(matrix, nx, ny));
               }
           }
           return dp[x][y];
       }
    }