leetcode329 Longest Increasing Path in a Matrix

Given an integer matrix, find the length of the longest increasing path.

From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).

Example 1:

Input: nums = 
[
  [9,9,4],
  [6,6,8],
  [2,1,1]
] 
Output: 4 
Explanation: The longest increasing path is[1, 2, 6, 9].

Example 2:

Input: nums = 
[
  [3,4,5],
  [3,2,6],
  [2,2,1]
] 
Output: 4 
Explanation: The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.

思路就是dfs搜索加动态存储

但是对数据的处理及存储方式不同会对运行速度造成很大影响。下面列出两种方法,第一种是目前details区最快速的算法,第二种是自己写的。在本机的运行速度分别为10ms与50ms.

两种方法对于数据处理的区别主要在(用fast代表快速算法,slow同理):

fast创建包含一位数字的数组用来存储最终结果(用数组是为了保证值的传递性),并在深度搜索的过程中随时更新值

而slow在最后再次遍历dp数组找最大值;

fast在向四个方向扩展过程中不断更新当前最大方向所对应的最大深度

而slow写了一个函数取四个方向中的最大深度;

扫描二维码关注公众号,回复: 4904821 查看本文章

solution 1:

public int longestIncreasingPath(int[][] matrix) {
        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return 0;
        } 
        int rows = matrix.length;
        int cols = matrix[0].length;
        
        
        int[] global = new int[]{1};
        int[][] dp = new int[rows][cols];
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                dfs(matrix, i, j, dp, global);
            }
        }
        
        return global[0];
        
    }
    
    private int dfs(int[][] matrix, int row, int col, int[][] dp, int[] global) {
        if(dp[row][col] != 0) {
            return dp[row][col];
        }
        
        int rows = matrix.length;
        int cols = matrix[0].length;
        int curVal = matrix[row][col];
        int leftVal = col - 1 >= 0 ? matrix[row][col - 1] : Integer.MIN_VALUE;
        int rightVal = col + 1 < cols ? matrix[row][col + 1] : Integer.MIN_VALUE;
        int topVal = row - 1 >= 0 ? matrix[row - 1][col] : Integer.MIN_VALUE;
        int bottomVal = row + 1 < rows ? matrix[row + 1][col] : Integer.MIN_VALUE;
        
        if(curVal >= leftVal && curVal >= rightVal && curVal >= topVal && curVal >= bottomVal) {
            dp[row][col] = 1;
            return 1;
        }
        
        if(col - 1 >= 0 && curVal < leftVal) {
            dp[row][col] = dfs(matrix, row, col - 1, dp, global) + 1;
        }
        
        if(col + 1 < cols && curVal < rightVal) {
            dp[row][col] = Math.max(dp[row][col], dfs(matrix, row, col + 1, dp, global) + 1);
        }
        
        if(row - 1 >= 0 && curVal < topVal) {
            dp[row][col] = Math.max(dp[row][col], dfs(matrix, row - 1, col, dp, global) + 1);
        }
        
        if(row + 1 < rows && curVal < bottomVal) {
            dp[row][col] = Math.max(dp[row][col], dfs(matrix, row + 1, col, dp, global) + 1);
        }
        
        global[0] = Math.max(global[0], dp[row][col]);
        return dp[row][col];
    }

solution 2:

class Solution {
    public int longestIncreasingPath(int[][] matrix) {
        if(matrix==null || matrix.length==0 || matrix[0].length==0) return 0;
        int longestPath= 0, bottombound= matrix.length, rightbound= matrix[0].length;
        int[][] pathMatrix= new int[matrix.length][matrix[0].length];
        dfsPath(pathMatrix,matrix,bottombound,rightbound);
        for(int i=0; i<bottombound; i++){
            for(int j=0; j<rightbound; j++){
                longestPath= longestPath>pathMatrix[i][j]? longestPath: pathMatrix[i][j];
            }
        }
        return longestPath;
    }
    public void dfsPath(int[][] pathMatrix,int[][] matrix,int rowm,int colm){
        for(int row=0; row<rowm; row++){
            for(int col=0; col<colm; col++){
                dfsPathCore(pathMatrix,matrix,rowm,colm,row,col);
            }
        }
    }
    public int dfsPathCore(int[][] pathMatrix,int[][] matrix,int rowm,int colm,int row,int col){
        if(pathMatrix[row][col]!=0)   return pathMatrix[row][col];
        int up=0,right=0,low=0,left=0;
        if(row-1>-1){
            if(matrix[row][col]>matrix[row-1][col])
                up= dfsPathCore(pathMatrix,matrix,rowm,colm,row-1,col);
        }
        if(col+1<colm){
            if(matrix[row][col]>matrix[row][col+1])
                right= dfsPathCore(pathMatrix,matrix,rowm,colm,row,col+1);
        }
        if(row+1<rowm){
            if(matrix[row][col]>matrix[row+1][col])
                low= dfsPathCore(pathMatrix,matrix,rowm,colm,row+1,col);
        }
        if(col-1>-1){
            if(matrix[row][col]>matrix[row][col-1])
                left= dfsPathCore(pathMatrix,matrix,rowm,colm,row,col-1);
        }
        
        pathMatrix[row][col]= 1+maxInFour(up,right,low,left);
        return pathMatrix[row][col];
    }
    public int maxInFour(int u,int r,int b,int l){
        int res= u;
        if(res<r)
            res=r;
        if(res<b)
            res=b;
        if(res<l)
            res=l;
        return res;
    }
}

将slow按照fast改进:11ms

class Solution {
    public int longestIncreasingPath(int[][] matrix) {
        if(matrix==null || matrix.length==0 || matrix[0].length==0) return 0;
        int longestPath= 0, bottombound= matrix.length, rightbound= matrix[0].length;
        int[][] pathMatrix= new int[matrix.length][matrix[0].length];
        int[] global= new int[]{0};
        dfsPath(pathMatrix,matrix,bottombound,rightbound,global);
        return global[0];
    }
    public void dfsPath(int[][] pathMatrix,int[][] matrix,int rowm,int colm,int[] global){
        for(int row=0; row<rowm; row++){
            for(int col=0; col<colm; col++){
                dfsPathCore(pathMatrix,matrix,rowm,colm,row,col,global);
            }
        }
    }
    public int dfsPathCore(int[][] pathMatrix,int[][] matrix,int rowm,int colm,int row,int col,int[] global){
        if(pathMatrix[row][col]!=0)   return pathMatrix[row][col];
        int up=0,right=0,low=0,left=0,max=0;
        if(row-1>-1){
            if(matrix[row][col]>matrix[row-1][col]){
                up= dfsPathCore(pathMatrix,matrix,rowm,colm,row-1,col,global);
                max= max>=up? max:up;
            }
        }
        if(col+1<colm){
            if(matrix[row][col]>matrix[row][col+1]){
                right= dfsPathCore(pathMatrix,matrix,rowm,colm,row,col+1,global);
                max= max>=right? max:right;
            }
        }
        if(row+1<rowm){
            if(matrix[row][col]>matrix[row+1][col]){
                low= dfsPathCore(pathMatrix,matrix,rowm,colm,row+1,col,global);
                max= max>=low? max:low;
            }
                
        }
        if(col-1>-1){
            if(matrix[row][col]>matrix[row][col-1]){
                left= dfsPathCore(pathMatrix,matrix,rowm,colm,row,col-1,global);
                max= max>=left? max:left;
            }
        }
        pathMatrix[row][col]= 1+max;
        global[0]= global[0]>=pathMatrix[row][col]? global[0]:pathMatrix[row][col];
        return pathMatrix[row][col];
    }
}
 

猜你喜欢

转载自blog.csdn.net/better_girl/article/details/85957246