这道题目是困难级别的,原题目地址leetcode,我刚开始没想出头绪,看了题解,才想到用深度优先搜索,仅此而已
给定一个整数矩阵,找出最长递增路径的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。
示例 1:
输入: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
输出: 4
解释: 最长递增路径为 [1, 2, 6, 9]。
示例 2:
输入: nums =
[
[3,4,5],
[3,2,6],
[2,2,1]
]
输出: 4
解释: 最长递增路径是 [3, 4, 5, 6]。注意不允许在对角线方向上移动。
如果单纯的用深度优先搜索,会超时。为避免重复计算,记录已计算过,因为每一格的最长路径是固定的。以示例1来说明,
[
[9,9,4],
[6,6,8],
[2,1,1]
]
用这么一个二维数组来记录结果。咱们先人脑遍历。
[
[0,0,0],
[0,0,0],
[0,0,0]
]
最小的数字是1,那么这两个位置,最长路径就是1,即本身。
[0,0,0],
[0,0,0],
[0,0,1]
向外扩散一步
[0,0,0],
[0,0,0],
[0,1,1]
向外扩散一步
[0,0,0],
[0,2,0],
[2,1,1]
两个2都向外扩散一步
[0,3,0],
[3,2,3],
[2,1,1]
最后得到结果
[4,3,1],
[3,2,3],
[2,1,1]
即,求某一个单元格的最大路径,先假设它周围四格的最大路径已经算出来了(人脑不擅长递归),如果中间这个单元格的数字,大于相邻的单元格,那最大路径就是相邻单元格最大路径+1,这样最多可求得四个值,取四个值中最大的那个。
如果文字不太好理解,直接看代码。
class Solution {
public int longestIncreasingPath(int[][] matrix) {
if(null == matrix || matrix.length == 0 || matrix[0].length == 0){
return 0;
}
int res = 0;
row = matrix.length;
col = matrix[0].length;
int[][] mem = new int[row][col];
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
res = Math.max(res, dfs(mem, matrix, i, j)); // 取出res中最大的那个
}
}
return res;
}
public int row, col;
public int[] x = new int[]{1, -1, 0, 0}; // 上下左右四个方向
public int[] y = new int[]{0, 0, 1, -1};
private int dfs(int[][] mem, int[][] matrix,int i, int j){
if(mem[i][j] != 0){
return mem[i][j];
}
mem[i][j] == 1; // 初始值设置为1
for(int k = 0; k < 4; k++){
int b_row = i + x[k];
int b_col = j + y[k];
if(b_row >= 0 && b_col >= 0 && b_col < col && b_row < row && matrix[i][j] > matrix[b_row][b_col]){ // 比相邻单元格大,就参与计算
mem[i][j] = Math.max(mem[i][j], dfs(mem, matrix, b_row, b_col) + 1);
}
}
return mem[i][j]; // 返回此单元格的最大路径
}
}