剑指 Offer II 112. 最长递增路径(329. 矩阵中的最长递增路径)

题目:

思路:

【1】深度优先搜索的方式

代码展示:

记忆化深度优先搜索(对已经遍历过的进行记录,达到优化的效果)

//时间8 ms击败79.10%
//内存43.1 MB击败5.3%
class Solution {
    public int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    public int rows, columns;

    public int longestIncreasingPath(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        }
        rows = matrix.length;
        columns = matrix[0].length;
        int[][] memo = new int[rows][columns];
        int ans = 0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < columns; ++j) {
                ans = Math.max(ans, dfs(matrix, i, j, memo));
            }
        }
        return ans;
    }

    public int dfs(int[][] matrix, int row, int column, int[][] memo) {
        if (memo[row][column] != 0) {
            return memo[row][column];
        }
        ++memo[row][column];
        for (int[] dir : dirs) {
            int newRow = row + dir[0], newColumn = column + dir[1];
            if (newRow >= 0 && newRow < rows && newColumn >= 0 && newColumn < columns && matrix[newRow][newColumn] > matrix[row][column]) {
                memo[row][column] = Math.max(memo[row][column], dfs(matrix, newRow, newColumn, memo) + 1);
            }
        }
        return memo[row][column];
    }
}

 

深度优先搜索的方式

//但是这种原本的深度优先搜索的模板容易导致时间超时,因为会存在大量的重复遍历的情况
class Solution {
    public int longestIncreasingPath(int[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;
        //构建浏览标志
        int[][] flag = new int[n][m];
        //填充默认标志0,表示未被遍历过
        for (int i = 0; i < n; i++){
            Arrays.fill(flag[i],0);
        }

        int max = 0;
        for (int i = 0; i < n; i++){
            for (int j = 0; j < m; j++){
                max = Math.max(max,dfsIncreasingPath(matrix,i,j,flag));
            }
        }

        return max;
    }

    public int dfsIncreasingPath(int[][] matrix, int col, int row,int[][] flag) {
        //已经被遍历过的地方就不需要重复遍历了
        if (flag[col][row] == 1) return 0;
        //标识已经遍历过
        flag[col][row] = 1;
        int count = 1;
        int[][] dire = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
        for (int i = 0; i < dire.length; i++){
            int newCol = col + dire[i][0];
            int newRow = row + dire[i][1];
            //四个方向的遍历应该在边界值内,且下一步的应该比当前值要大
            if (newCol >= 0 && newRow >=0 && newCol < matrix.length && newRow < matrix[0].length && matrix[newCol][newRow] > matrix[col][row]){
                count = Math.max( count, 1 + dfsIncreasingPath(matrix,newCol, newRow, flag));
            }
        }
        //恢复标记
        flag[col][row] = 0;
        return count;
    }
}

 

posted @ 2023-04-28 12:30  忧愁的chafry  阅读(19)  评论(0编辑  收藏  举报