[Leetcode 329] Longest Increasing Path in a Matrix
Question
Leetcode 329: Longest Increasing Path in a Matrix
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).
Examples:
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
Method 1
本题最明显的接法肯定是使用DFS,但是如果对于每个起点都进行一遍DFS肯定复杂度太高。用一点点DP的思想来存下已经计算的结果就好了。
注意的一点是找的是increasing path,所以如果在DFS的中间碰到之前走过的一个点,那么这个点存的最长长度的path一定和已经走的path没有重叠。
class Solution:
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
dirs = [(1,0), (0,1), (-1,0), (0,-1)]
lengths =[[0] * len(matrix[0]) for _ in range(len(matrix))]
def find_length(i,j):
if lengths[i][j] != 0:
return lengths[i][j]
for dx, dy in dirs:
x = i + dx
y = j + dy
if 0 <= x < len(matrix) and 0 <= y < len(matrix[0]) and matrix[x][y] > matrix[i][j]:
lengths[i][j] = max(lengths[i][j], find_length(x, y))
lengths[i][j] += 1
return lengths[i][j]
max_len = 0
for i in range(len(matrix)):
for j in range(len(matrix[i])):
max_len = max(max_len, find_length(i,j))
return max_len
Method 2
另一个想法是把matrix想成一个有向图 directed graph,每个数会指向它上下左右的比他大的数。那么这个最长的path的起点一定是一个只有出度的数。所以进行 topological sort,在每个round的中先找出所有入度为0的数, 根据他们的边更新graph,就会有新的入度为0的数出现。每个round代表了path的长度加一。