Given an m x n integers matrix, return the length of the longest increasing path in matrix.
From each cell, you can either move in four directions: left, right, up, or down. You may not move diagonally or move outside the boundary (i.e., wrap-around is not allowed).
solutions
dfs w/ memoization
Initially, I thought that we needed to do something fancy because a simple DFS + memoization wouldn’t work, as we would need to memoize a visited array as well.
However, a big realization here is that the visited array is unnecessary as our valid paths are necessary monotonically increasing, meaning that it’s impossible to visit a node that’s already been visited.
As such, a simple DFS solution with memoization works here.
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
dirs = [[0,1],[1,0],[0,-1],[-1,0]]
memo = {}
def dfs(x, y):
if (x, y) in memo:
return memo[(x, y)]
best_subpath = 0
for d in dirs:
nx, ny = x+d[0], y+d[1]
if 0 <= nx < m and 0 <= ny < n:
if matrix[nx][ny] > matrix[x][y]:
best_subpath = max(best_subpath, dfs(nx, ny))
memo[(x, y)] = best_subpath + 1
return memo[(x, y)]
ans = 0
for i in range(m):
for j in range(n):
ans = max(ans, dfs(i, j))
return ansbfs w/ topological sort
Another way this question can be solved is by imagining the matrix as a directed acyclic graph, where directed edges exist from adjacent cells to when .
def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
m, n = len(matrix), len(matrix[0])
dirs = [[0,1],[1,0],[0,-1],[-1,0]]
indegrees = Counter()
memo = {}
# construct indegrees
for x in range(m):
for y in range(n):
for dx, dy in dirs:
nx, ny = x+dx, y+dy
if 0 <= nx < m and 0 <= ny < n:
if matrix[nx][ny] > matrix[x][y]:
indegrees[(nx, ny)] += 1
# initialize queue with 0 indegree nodes
q = deque()
for x in range(m):
for y in range(n):
if indegrees[(x, y)] == 0:
q.append((x, y))
ans = 0
while q:
level_len = len(q)
for _ in range(level_len):
x, y = q.popleft()
for dx, dy in dirs:
nx, ny = x+dx, y+dy
if 0 <= nx < m and 0 <= ny < n:
if matrix[nx][ny] > matrix[x][y]:
indegrees[(nx, ny)] -= 1
if indegrees[(nx, ny)] == 0:
q.append((nx, ny))
ans += 1
return ans