Given an integer matrix, find the length of the longest increasing path.
From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).
Example 1:
nums = [
[9,9,4],
[6,6,8],
[2,1,1]
]
Return 4
The longest increasing path is [1, 2, 6, 9]
.
Example 2:
nums = [
[3,4,5],
[3,2,6],
[2,2,1]
]
Return 4
The longest increasing path is [3, 4, 5, 6]
. Moving diagonally is not allowed.
第一种方法,递归。很明显,时间超时,通不过。
class Solution {
public int longestIncreasingPath(int[][] matrix) {
if (matrix == null || matrix.length == || matrix[].length == ) return ;
int[] max = new int[];
boolean[][] visited = new boolean[matrix.length][matrix[].length];
for (int i = ; i < matrix.length; i++) {
for (int j = ; j < matrix[].length; j++) {
helper(matrix, visited, i, j, matrix[i][j], true, , max);
}
}
return max[];
} public void helper(int[][] matrix, boolean[][] visited, int i, int j, int prev, boolean isStart, int size, int[] max) {
if (i < || i >= matrix.length || j < || j >= matrix[].length || visited[i][j]) return;
if (matrix[i][j] <= prev && !isStart) return; visited[i][j] = true;
size++;
max[] = Math.max(max[], size); helper(matrix, visited, i + , j, matrix[i][j], false, size, max);
helper(matrix, visited, i - , j, matrix[i][j], false, size, max);
helper(matrix, visited, i, j + , matrix[i][j], false, size, max);
helper(matrix, visited, i, j - , matrix[i][j], false, size, max);
visited[i][j] = false;
}
}
第二种方法类似第一种方法,但是我们不会每次都对同一个位置重复计算。对于一个点来讲,它的最长路径是由它周围的点决定的,你可能会认为,它周围的点也是由当前点决定的,这样就会陷入一个死循环的怪圈。其实并没有,因为我们这里有一个条件是路径上的值是递增的,所以我们一定能够找到一个点,它不比周围的值大,这样的话,整个问题就可以解决了。
public class Solution {
public int longestIncreasingPath(int[][] A) {
int res = ;
if (A == null || A.length == || A[].length == ) {
return res;
}
int[][] store = new int[A.length][A[].length];
for (int i = ; i < A.length; i++) {
for (int j = ; j < A[].length; j++) {
if (store[i][j] == ) {
res = Math.max(res, dfs(A, store, i, j));
}
}
}
return res;
} private int dfs(int[][] A, int[][] store, int i, int j) {
if (store[i][j] != ) {
return store[i][j];
}
int left = , right = , up = , down = ;
if (j + < A[].length && A[i][j + ] > A[i][j]) {
right = dfs(A, store, i, j + );
}
if (j > && A[i][j - ] > A[i][j]) {
left = dfs(A, store, i, j - );
}
if (i + < A.length && A[i + ][j] > A[i][j]) {
down = dfs(A, store, i + , j);
}
if (i > && A[i - ][j] > A[i][j]) {
up = dfs(A, store, i - , j);
}
store[i][j] = Math.max(Math.max(up, down), Math.max(left, right)) + ;
return store[i][j];
}
}