[LeetCode] 329. Longest Increasing Path in a Matrix_Hard tag: Dynamic Programming, DFS, Memoization
2018-07-25 06:25 Johnson_强生仔仔 阅读(262) 评论(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.
这个题目我理解为还是Dynamic Programming, 虽然说是加入了memoization, 但是DP的本质不本来也是memoization么? anyways, 这个题目就是用DFS, 但是每次的结果我们会存
在dp数组里面, 另外有个visited set, 去标记我们是否已经visited过了, 已经得到这个元素的值, 如果是的话直接返回, 节省time,
另外 function的话就是A[i][j] = max(A[i][j], helper(neig) + 1), 需要注意的是dp数组存的是以该点作为结束的点的最大值, 那么我们就需要向小的值去search, 所以有
matrix[i][j] > matrix[nr][nc] 的判断在那里.
1. Constraints
1) empty , return 0
2) element will be interger, 有duplicates, 但是increasing 是绝对的, 所以不用担心duplicates
2. Ideas
memoization DFS, T: O(m*n) S: O(m*n)
1) edge case
2) helper dfs function, 向4个邻居方向search, max(A[i][j], helper(neig) + 1), 最开始的时候加判断, 如果flag, 直接返回dp[i][j]; 或者直接用dict()来存;
3) for lr, for lc, ans = max(ans, helper(i,j))
4) return ans
3. code
class Solution: def longestIncreasingPath(self, matrix: List[List[int]]) -> int: if not matrix or not matrix[0]: return 0 ans = 0 d = dict() m, n = len(matrix), len(matrix[0]) for i in range(m): for j in range(n): ans = max(ans, self.dfs(matrix, i, j, d)) return ans def dfs(self, matrix, i, j, d): if (i, j) not in d: m, n = len(matrix), len(matrix[0]) ans = 0 dirs = [(1, 0), (-1, 0), (0, 1), (0, -1)] for d1, d2 in dirs: x, y = i + d1, j + d2 if 0 <= x < m and 0 <= y < n and matrix[x][y] > matrix[i][j]: ans = max(ans, self.dfs(matrix, x, y, d)) d[(i, j)] = 1 + ans return d[(i, j)]
class Solution: def longestIncreasePath(self, matrix): if not matrix or not matrix[0]: return 0 lrc, ans, dirs = [len(matrix), len(matrix[0])], 0, [(1,0), (-1, 0), (0,1), (0,-1)] dp, visited = [[1]*lrc[1] for _ in range(lrc[0])] , set()
def helper(i, j): if (i, j) in visited: return dp[i][j]
visited.add((i, j)) for c1, c2 in dirs: nr, nc = c1 + i, c2 + j if 0 <= nr < lrc[0] and 0 <= nc < lrc[1] and matrix[i][j] > matrix[nr][nc]: dp[i][j] = max(dp[i][j], helper(nr, nc) + 1) return dp[i][j] for i in range(lrc[0]): for j in range(lrc[1]): ans = max(ans, helper(i,j)) return ans
4. Test cases
[ [9,9,4], [6,6,8], [2,1,1] ] Output: 4