【LeetCode 剑指 Offer II 112. 最长递增路径】深搜+记忆化搜索

一、标题及题目

LeetCode 剑指 Offer II 112. 最长递增路径

**给定一个 m x n整数矩阵 matrix ,找出其中 最长递增路径 的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)

二、解题思路

1:分析题意

我们需要找到一条最长的递增路径的长度。

1)分析部分情况

那么我们分析一个普遍性的情况,如果matrix[x][y]点的值小于它周围的某一个值(设这个点为[tx][ty]),那么是不是[x][y]点与[tx][ty]存在一条增长路径。接着可得[x][y]点与[tx][ty]增长路径的长度等于从点[tx][ty]开始的最长增长路径的长度+1。

2) 分析较全情况

在上一步了我们分析了[x][y]的某条增长路径的情况,接着我们分析最长的情况,我们都学过或听过贪心的思路(及局部最优拓展到全局最优)。那么在这道题里这种思路也是正确的。所有我们需要确定每个点所能产生的最长增长路径。及[x][y]点开始的最长的增长路径的长度从四个方向开始的路径的最大值。 m a t r i x [ x ] [ y ] < m a t r i x [ t x ] [ t y ] 时 : matrix[x][y] <matrix[tx][ty]时: matrix[x][y]<matrix[tx][ty]: l e n g t h ( i ) [ x ] [ y ] = l e n g t h [ t x ] [ t y ] + 1 ; length(i)[x][y] = length[tx][ty]+1; lengthi[x][y]=length[tx][ty]+1; m a t r i x [ x ] [ y ] > = m a t r i x [ t x ] [ t y ] 时 : matrix[x][y]>=matrix[tx][ty]时: matrix[x][y]>=matrix[tx][ty]: l e n g t h ( i ) [ x ] [ y ] = 1 length(i)[x][y] = 1 lengthi[x][y]=1 l e n g t h [ x ] [ y ] = m a x ( l e n g t h ( i ) [ x ] [ y ] ∣ i 属 于 0 , 1 , 2 , 3 ) length[x][y] = max(length(i)[x][y]|i属于0,1,2,3 ) length[x][y]=max(lengthi[x][y]i0123)

3)提高代码效率

由于我们在计算每个节点开始的最长路径时常常需要计算其他节点开始的最长路径,那么我们可以将已经计算过的点的最长路径保存下来,方便别的节点计算时再调用该节点的最长路径。

代码实现

class Solution {
    int[][] temp;                                  //temp即为保存个个节点最长路径的二维数组
    int[][] find = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};    //find数组保存了朝着四个方向移动时
                                                             //x,y的变化值
    public int longestIncreasingPath(int[][] matrix) {
     int m = matrix.length;
     int n = matrix[0].length;
     int ans = 0;   
        temp = new int[m][n];
     for(int i =0;i<m;++i){
         for(int j = 0;j<n;++j){
             if(temp[i][j] == 0){
                 ans = Math.max(ans,dfs(i,j,matrix,m,n));
             }
         }
     }   
        return ans;
    }
    
    public int dfs(int x ,int y,int[][] matrix,int m,int n){
        int ans = 1;
            int tx;
            int ty;
                for(int j  = 0;j<4;j++){
                    tx = x+find[j][0];
                    ty = y+find[j][1];
                    if(tx<0 || ty< 0 || tx>=m || ty>=n){  //如果tx,ty 的角标越界我们continue,计算
                                                          //x,y的另外一个方向
                        continue;
                    }
                    if(matrix[x][y]<matrix[tx][ty]){
                          if(temp[tx][ty] == 0)//及tx,ty点未被访问过
                          ans  =Math.max(dfs(tx,ty,matrix,m,n)+1,ans);
                        else
                           ans = Math.max(temp[tx][ty]+1,ans);
                    }
                }
        temp[x][y] = ans;  //保存该节点开始的最长递增路径
        return ans;
    }
}

个人能力有限,解法可能并非较优,希望大家多多包涵。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值