跳到主要内容

329. Max Rising Path

Longest Increasing Path in a Matrix

必学的矩阵DFS题型 大概就是像329号这题

要求找出最长的严格递增路径

限制是 站在每个点上企图延伸路径时

只能考虑东南西北任一方位 不能开斜线模式

当然 也不能跑离矩阵 因此边界管制是首要操作

轻松扫描全局答案

对于矩阵的每个元素matrix[i][j]

我们都要尝试由它为起点 寻找最长的递增路径长度

因此先开一个尺寸与matrix完全一致的maxRisingPath

初始化时 maxRisingPath所有元素都是-1 象徵着尚未访问过

然后对于每个matrix[i][j] 我们先看看四个 潜在 邻居:

  1. matrix[i][j + 1] 向东
  2. matrix[i + 1][j] 向南
  3. matrix[i][j - 1] 向西
  4. matrix[i - 1][j] 向北

轮到邻居xx做边界检查时 一旦验证邻居xx确实存在

那就能继续看 xx的值是否比matrix[i][j]更大

更大的话 再来查 xx为起点的最长递增路径长度

拿来加1便是 matrix[i][j]出发向xx走时 能得到的最长递增路径长度

因此如果邻居xxmaxRisingPath显示-1

说明xx尚未被访问过 就得先拿DFS访问xx

一旦xx的最长递增路径长度定下来 假设叫kk

我们就采取 maxRisingPath[i][j]=max(maxRisingPath[i][j],1+k)maxRisingPath[i][j] = max(maxRisingPath[i][j], 1 + k)

的方针更新maxRisingPath[i][j]

在更新好maxRisingPath[i][j]别忘了和历史最大值比

Matrix_DFS Efficiency 时间和空间复杂度都是O(mn)O(mn) 其中mmnn分别是矩阵的行数和列数

第329题虽然官方标记Hard 但其实不难 甚至偏简单 非常适合练基础功


class MaxRisingPath: # LeetCode Q.329.
def __init__(self):
self.matrix = []
self.max_rising_path = []
self.max_rising_len = 1

def find_longest_rising_path(self, matrix: list[list[int]]) -> int:
self.matrix = matrix

# An entry's max rising path value is -1 if this entry is unsearched.
# Otherwise, max rising path value is the finalized value w.r.t. entry.
self.max_rising_path = [[-1] * len(matrix[0]) for _ in range(len(matrix))]

self.max_rising_len = 1 # Base case.

for row_idx in range(len(matrix)):
for col_idx in range(len(matrix[0])):
if self.max_rising_path[row_idx][col_idx] == -1:
self._dfs_rising_path(row_idx, col_idx)

return self.max_rising_len

def _dfs_rising_path(self, row_idx: int, col_idx: int) -> None:
self.max_rising_path[row_idx][col_idx] = 1 # Base case: a path of only current entry.

neighbors: list[tuple[int, int]] = [
(row_idx + 1, col_idx), (row_idx - 1, col_idx), # South & North.
(row_idx, col_idx + 1), (row_idx, col_idx - 1) # East & West.
]

for neighbor_row_idx, neighbor_col_idx in neighbors:
# Inbound checks on row & col indices.
if not (0 <= neighbor_row_idx < len(self.matrix)): continue

if not (0 <= neighbor_col_idx < len(self.matrix[0])): continue

# Only consider neighbors that are bigger than current entry.
if self.matrix[row_idx][col_idx] < self.matrix[neighbor_row_idx][neighbor_col_idx]:
# Unsearched neighbor.
if self.max_rising_path[neighbor_row_idx][neighbor_col_idx] == -1:
self._dfs_rising_path(neighbor_row_idx, neighbor_col_idx)

rising_len = 1 + self.max_rising_path[neighbor_row_idx][neighbor_col_idx]

if rising_len > self.max_rising_path[row_idx][col_idx]:
self.max_rising_path[row_idx][col_idx] = rising_len

if rising_len > self.max_rising_len: self.max_rising_len = rising_len