题目:
//给定一个整数矩阵,找出最长递增路径的长度。
//
// 对于每个单元格,你可以往上,下,左,右四个方向移动。 你不能在对角线方向上移动或移动到边界外(即不允许环绕)。
//
// 示例 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]。注意不允许在对角线方向上移动。
//
// Related Topics 深度优先搜索 拓扑排序 记忆化
// 402 0
关键词:深度优先算法
思路:遍历矩阵中的每个元素,从每个元素开始,依次按一定的顺序(如 右-下-左-上)进行迭代处理,判断相邻的元素是否满足可以迭代的条件,如果满足则将递增路径+1,然后比较得出最长路径即可。
上面的思路虽然是正确的,但是没有考虑效率问题,如果是下面的矩阵,会有超时问题。
解决思路:使用缓存。
以上面的矩阵举例,按照题目规则,数字 65只能从上面和左面两个方向进入,而不管是哪个方向进入的,65之后能得到的最长路径是固定的,所以可以使用缓存减少迭代的次数。
建立一个相同大小的矩阵用于缓存。
代码(抄的):
class Solution {
int[][] state = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
public int longestIncreasingPath(int[][] matrix) {
int height = matrix.length;
if (height == 0) {
return 0;
}
int width = matrix[0].length;
// 缓存,存储每个位置所能达到的最长路径
int[][] cache = new int[height][width];
int max = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
max = Math.max(dfs(cache, matrix, i, j), max);
}
}
return max;
}
public int dfs(int[][] cache, int[][] matrix, int i, int j) {
if (cache[i][j] != 0) {
return cache[i][j];
}
cache[i][j] = 1;
for (int[] s : state) {
int x = i + s[0];
int y = j + s[1];
if (x >= 0 && x < matrix.length
&& y >= 0 && y < matrix[0].length
&& matrix[i][j] < matrix[x][y]) {
cache[i][j] = Math.max(cache[i][j], dfs(cache, matrix, x, y) + 1);
}
}
return cache[i][j];
}
}