每日一题算法:2020年7月26日 [矩阵中的最长递增路径] longestIncreasingPath

2020年7月26日 矩阵中的最长递增路径 longestIncreasingPath

在这里插入图片描述

class Solution {
    public int longestIncreasingPath(int[][] matrix) {

    }
}

解题思路:

这道题还是使用动态规划+递归的思想,首先使用递归+遍历的方式,计算每一个节点作为起点时最大的长度。

比如下面图所示。

在这里插入图片描述

递归步骤:

第一步,坐标(0,0)寻找周围四个点的值进行判断,先根据大小分为以下两种情况。

1:大于该点的值

2:小于该点的值

我们可以看到4和8都是比2大,所以进行第一种处理,这里的意义就是,以(0,0)为起点得到的最大长度必定比(0,1)的大1,所以我们只需要得到(0,1)这个点的最大长度+1就能得到该点的最大长度。

当然,我们是从周围四个点中找出最大的来继承他的值。

但是,(0,1)这个点目前最大长度是0,说明还没有得到过最大长度,所以,如果周围的这个点长度为0,则先计算该点的长度再回来计算当前点。

为了简单我们以(1,0) 8 为样例,现在我们要得到(0,0)的长度先要得到(1,0)的长度,而计算(1,0)的长度,发现周围的四个点中有下面的这个点(2,0)的值比当前点8大,所以用(2,0)的长度+1来作为当前节点的长度,而(2,0)的长度也是0,所以我们还是要递归求这个(2,0)点的长度。

(2,0)这个点的长度是可以求的,因为周围所有点的值都比当前点小,所以当前点的值为1。
在这里插入图片描述

由于递归的关系,依次回到(1,0)和(0,0)节点
在这里插入图片描述

右侧这一点(0,1)也同理
在这里插入图片描述

通过(0,1)得到的长度5大于(1,0)得到的长度3,所以选择5作为当前节点的长度

由于使用遍历的算法,所以现在计算(0,1)的长度,而(0,1)的长度已经计算过了,(在数组2中的值不为0表示已经计算),所以跳过该节点的计算。

继续递归计算(2,0)的长度,0表示没有计算长度,比较周围4个点,左边这个点已经计算过,所以可以直接得到长度5,下面这个节点长度没有计算,所以递归计算下面节点的长度。
在这里插入图片描述

依次方式递归所有节点。
在这里插入图片描述

使用递归的方式计算每一个节点作为起点的长度,并且把它记录下来,如果计算一个节点时,这个节点已经被计算过了,那就直接跳过这一次递归。

代码实现:

在这里插入图片描述

int[][] array;
int[][] matrix1;
int max=1;
public int longestIncreasingPath(int[][] matrix) {
    if (matrix.length==0)
        return 0;
    matrix1=matrix;
    array=new int[matrix.length][matrix[0].length];
    for (int i=0;i<matrix.length;i++){
        for (int j=0;j<matrix[0].length;j++){
            longestIncreasingPath2(i,j );
        }
    }

    return max;


}
public void longestIncreasingPath2(int x,int y){
    if (array[x][y]==0){


        //判断右边一个,如果右边已经存在,直接使用,否则则先判断右边这个点
        if (x+1<matrix1.length&&matrix1[x][y]<matrix1[x+1][y]){
            if (array[x+1][y]==0){
                longestIncreasingPath2(x+1,y );
            }
            array[x][y]=Integer.max(array[x+1][y]+1,array[x][y]);
        }
        if (x-1>=0&&matrix1[x][y]<matrix1[x-1][y]){
            if (array[x-1][y]==0){
                longestIncreasingPath2(x-1,y );
            }
            array[x][y]=Integer.max(array[x-1][y]+1,array[x][y]);
        }
        if (y+1<matrix1[0].length&&matrix1[x][y]<matrix1[x][y+1]){
            if (array[x][y+1]==0){
                longestIncreasingPath2(x,y+1);
            }
            array[x][y]=Integer.max(array[x][y+1]+1,array[x][y]);
        }
        if (y-1>=0&&matrix1[x][y]<matrix1[x][y-1]){
            if (array[x][y-1]==0){
                longestIncreasingPath2(x,y-1);
            }
            array[x][y]=Integer.max(array[x][y-1]+1,array[x][y]);
        }
        if (array[x][y]==0)
            array[x][y]=1;
        max=Integer.max(max,array[x][y]);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值