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.
唉,好长时间没做动态规划,最后才想起来用动态规划备忘录法
自己刚刚开始写的傻瓜算法:
public int longestIncreasingPath(int[][] matrix) {
int result=0;
if(matrix==null||matrix.length==0){
return result;
}
int m=matrix.length;
int n=matrix[0].length;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
int increasingDistance = getIncreasingDistance(i,j,matrix);
result=result>increasingDistance?result:increasingDistance;
}
}
return result;
}
public int getIncreasingDistance(int i, int j, int[][] matrix) {
// TODO Auto-generated method stub
int upLongestDistance=0;
int downLongestDistance=0;
int leftLongestDistance=0;
int rightLongestDistance=0;
int m=matrix.length;
int n=matrix[0].length;
//从上走
if(i-1>=0&&matrix[i-1][j]>matrix[i][j]){
upLongestDistance=getIncreasingDistance(i-1, j, matrix)+1;
}
//从下走
if(i+1<m&&matrix[i+1][j]>matrix[i][j]){
downLongestDistance=getIncreasingDistance(i+1, j, matrix)+1;
}
//从左走
if(j-1>=0&&matrix[i][j-1]>matrix[i][j]){
leftLongestDistance=getIncreasingDistance(i, j-1, matrix)+1;
}
//从右走
if(j+1<n&&matrix[i][j+1]>matrix[i][j]){
rightLongestDistance=getIncreasingDistance(i, j+1, matrix)+1;
}
int max=max(upLongestDistance, downLongestDistance, leftLongestDistance, rightLongestDistance);
return max>1?max:1;
}
public int max(int up, int down,
int left, int right) {
// TODO Auto-generated method stub
return ((up>down?up:down)>left?(up>down?up:down):left)>right?((up>down?up:down)>left?(up>down?up:down):left):right;
}
正确解法如下:
public class Solution {
int[][] dp;
int[][] directions = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
int m;
int n;
int[][] mx;
public int longestIncreasingPath(int[][] matrix) {
if (matrix==null || matrix.length==0 || matrix[0].length==0) return 0;
m = matrix.length;
n = matrix[0].length;
dp = new int[m][n];
mx = matrix;
int result = 0;
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
dp[i][j] = Integer.MIN_VALUE;
}
}
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) {
result = Math.max(result, DFS(i,j));
}
}
return result;
}
public int DFS(int i, int j) {
if (dp[i][j] != Integer.MIN_VALUE) return dp[i][j];
dp[i][j] = 1;
for (int[] dir : directions) {
int x = i + dir[0];
int y = j + dir[1];
if (x<0 || y<0 || x>=m || y>=n || mx[x][y]<=mx[i][j]) continue;
dp[i][j] = Math.max(dp[i][j], DFS(x,y)+1);
}
return dp[i][j];
}
}