[LeetCode][H 0329]行列中最長インクリメントパス(Java)(記憶化検索)
タイトルの説明:
整数行列を指定し、最長のインクリメントパスの長さを見つけます.
各セルについて、上、下、左、右の4つの方向に移動できます.対角線方向に移動したり、境界外に移動したりすることはできません(つまり、周囲を許可しません).
例1:
例2:
エラーの反省:
①また細かいところで間違えて、なんとプラス記号を忘れてしまいました...
②行列が空であることを無視して、配列の下に境界を越えた.
問題解決の考え方:
記憶化検索、私に与える感じはdfs+dpで、多くくだらないことを言わないで、例1を見ます
シーケンスを増やすため、理論的には、各点が到達できる最大値までの経路長を見つけて記録し、その後、それに着くたびに、この値をそのまま使えばいいのです.
int[][]memo=new int[行数][列数];//最大ロード長を格納するために使用
例1:memo
Javaコード(自分のコード):30 ms
より高速なJavaコード:9 ms
整数行列を指定し、最長のインクリメントパスの長さを見つけます.
各セルについて、上、下、左、右の4つの方向に移動できます.対角線方向に移動したり、境界外に移動したりすることはできません(つまり、周囲を許可しません).
例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]
。 。
エラーの反省:
①また細かいところで間違えて、なんとプラス記号を忘れてしまいました...
②行列が空であることを無視して、配列の下に境界を越えた.
問題解決の考え方:
記憶化検索、私に与える感じはdfs+dpで、多くくだらないことを言わないで、例1を見ます
シーケンスを増やすため、理論的には、各点が到達できる最大値までの経路長を見つけて記録し、その後、それに着くたびに、この値をそのまま使えばいいのです.
int[][]memo=new int[行数][列数];//最大ロード長を格納するために使用
例1:memo
[ [
[9,9,4], memo [1,1,2],
[6,6,8], ===> [2,2,1],
[2,1,1] [3,4,2]
] ]
, ,dfs , memo ; dfs memo 。
Javaコード(自分のコード):30 ms
//
// : 30 ms, Longest Increasing Path in a Matrix Java 29.14%
// : 49.2 MB, Longest Increasing Path in a Matrix Java 2.94%
class Solution {
int row,col;
int[][] memo;
int res = 0;
public int longestIncreasingPath(int[][] matrix) {
row = matrix.length;
if(row==0)return 0;
col = matrix[0].length;
memo = new int[row][col];
for(int i=0;i0&&matrix[x-1][y]>matrix[x][y]){
temp = dfs(matrix,x-1,y)+1;
}
//down
if(xmatrix[x][y]){
temp = Math.max(temp,dfs(matrix,x+1,y)+1);
}
//left
if(y>0&&matrix[x][y-1]>matrix[x][y]){
temp = Math.max(temp,dfs(matrix,x,y-1)+1);
}
//right
if(ymatrix[x][y]){
temp = Math.max(temp,dfs(matrix,x,y+1)+1);
}
return memo[x][y]=temp==0?1:temp;
}
}
より高速なJavaコード:9 ms
// 9 ms
// , , ,,
class Solution {
// dp
int[][] visited;
int m, n;
public int longestIncreasingPath(int[][] matrix) {
// null
if (matrix.length == 0 || matrix[0].length == 0) return 0;
//
m = matrix.length;
n = matrix[0].length;
int res = 1;
visited = new int[m][n];
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (visited[i][j] != 0) continue;
res = Math.max(res, dfs(matrix, i, j, Integer.MIN_VALUE));
}
}
return res;
}
public int dfs(int[][] matrix, int i, int j, int oldVal){
// ,
if (i < 0 || i >= m || j < 0 || j >= n || matrix[i][j] <= oldVal) return 0;
//
if (visited[i][j] == 0){
// dfs
int curVal = matrix[i][j];
int up = dfs(matrix, i + 1, j, curVal);
int down = dfs(matrix, i - 1, j, curVal);
int right = dfs(matrix, i, j + 1, curVal);
int left = dfs(matrix, i, j - 1, curVal);
//
visited[i][j] = 1 + Math.max(Math.max(up, down), Math.max(right, left));
}
return visited[i][j];
}
}