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]);
}
}