[LeetCode 329] Longest Increasin
2019-06-07 本文已影响0人
灰睛眼蓝
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:
Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
Example 2:
Input: nums =
[
[3,4,5],
[3,2,6],
[2,2,1]
]
Output: 4
Explanation: The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.
Solution: DFS + memorization
- 如果只用backtracking会超时
- 需要用一个记忆体matrix,对每个格子记录从它出发能达到的最长
path length
。 - DFS返回就是当前这个格子能够得到的最长
path length
,再找到最大的那个,就是结果。- DFS中,如果当前格子已经有值了,就说明已经找到了从它出发能够找到的最大长度,直接返回结果
- 再对其四个方向出发的邻居格子,递归调用DFS求解,
currentCellPath = 1 + neighborCellPath
- 最后返回
max currentCellPath
转自http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/
class Solution {
/************** backtracking DFS TimeOut****************************
public int longestIncreasingPath(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int[] longestPath = { 0 };
boolean [][] visited = new boolean[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
List<Integer> path = new ArrayList<> ();
path.add (matrix[i][j]);
visited[i][j] = true;
longestIncreasingPathHelper (matrix, visited, longestPath, path, i, j); //current path length
visited[i][j] = false;
}
}
return longestPath[0];
}
public void longestIncreasingPathHelper (int[][] matrix,
boolean[][] visited,
int[] longestPath,
List<Integer> path,
int row, int col) {
boolean canContinue = row >= 0 && row < matrix.length && col >= 0 && col < matrix[0].length &&
(matrix[row][col] > path.get (path.size () - 1) || path.size () == 1);
if (!canContinue) {
return;
}
// path.add (matrix[row][col]);
// visited[row][col] = true;
// System.out.println (Arrays.toString (path.toArray()));
longestPath[0] = Math.max (longestPath[0], path.size ());
int[][] directions = {{-1, 0},{0, 1},{1, 0},{0, -1}};
for (int[] direction : directions) {
int nextRow = row + direction[0];
int nextCol = col + direction[1];
path.add (matrix[row][col]);
visited[row][col] = true;
// System.out.println (Arrays.toString (path.toArray()));
longestIncreasingPathHelper (matrix, visited, longestPath, path, nextRow, nextCol);
path.remove (path.size () - 1);
visited[row][col] = false;
}
}
*******************************************************/
public int longestIncreasingPath(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int longestPath = 0;
int[][] longestPathEachCell = new int[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
longestPath = Math.max (longestPath, longestIncreasingPathHelper (matrix,longestPathEachCell, i, j));
}
}
return longestPath;
}
// for each cell, return its max path
public int longestIncreasingPathHelper (int[][] matrix, int[][] longestPathEachCell, int row, int col) {
// if it already has, then directly return it. AVOID TOO MANY DUPLICATED EXECUTION
if (longestPathEachCell[row][col] != 0)
return longestPathEachCell[row][col];
longestPathEachCell[row][col] = 1;
int[][] directions = {{-1, 0},{0, 1},{1, 0},{0, -1}};
for (int[] direction : directions) {
int nextRow = row + direction[0];
int nextCol = col + direction[1];
boolean canContinue = nextRow >= 0 && nextRow < matrix.length && nextCol >= 0 && nextCol < matrix[0].length && matrix[nextRow][nextCol] > matrix[row][col];
if (!canContinue)
continue;
longestPathEachCell[row][col] = Math.max (longestPathEachCell[row][col], 1 + longestIncreasingPathHelper(matrix, longestPathEachCell, nextRow, nextCol));
}
return longestPathEachCell[row][col];
}
}