↓快轉到主要內容
  1. LeetCode/

LeetCode 2328: Number of Increasing Paths in a Grid

·2 分鐘· ·
LeetCode Hard Dynamic-Programming Grid-Dp Memoization Topological-Sort Matrix
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-08-30

  • 提交紀錄:Accepted(一次通過)

解題思路
#

可以往四個方向走,一般的 Grid DP 會有環。但路徑要嚴格遞增,只能從小的走到大的,所以沒有環,是一個 DAG。

dp[cell] = 從這格出發的遞增路徑數:

dp[cell] = 1(只有自己)+ Σ dp[值比它大的鄰居]

依值由大到小處理,算到某格時,比它大的鄰居都已經算好了。答案是所有 dp 的總和。

我的解法
#

我 AC 的是記憶化 DFS:

from functools import cache

class Solution:
    def countPaths(self, grid: List[List[int]]) -> int:
        MOD = 10 ** 9 + 7
        m, n = len(grid), len(grid[0])

        @cache
        def dfs(r: int, c: int) -> int:            # 從 (r, c) 出發的遞增路徑數
            paths = 1
            for dr, dc in ((0, 1), (1, 0), (0, -1), (-1, 0)):
                nr, nc = r + dr, c + dc
                if 0 <= nr < m and 0 <= nc < n and grid[nr][nc] > grid[r][c]:
                    paths += dfs(nr, nc)
            return paths % MOD

        return sum(dfs(r, c) for r in range(m) for c in range(n)) % MOD

格子最多 10^5 個,最長的遞增路徑可能很深,遞迴有機會碰到深度上限。依值排序的迴圈版本不會有這個問題:

class Solution:
    def countPaths(self, grid: List[List[int]]) -> int:
        MOD = 10 ** 9 + 7
        m, n = len(grid), len(grid[0])
        dp = [[1] * n for _ in range(m)]
        cells = sorted(((grid[r][c], r, c) for r in range(m) for c in range(n)), reverse=True)
        for val, r, c in cells:                    # 由大到小
            for dr, dc in ((0, 1), (1, 0), (0, -1), (-1, 0)):
                nr, nc = r + dr, c + dc
                if 0 <= nr < m and 0 <= nc < n and grid[nr][nc] > val:
                    dp[r][c] = (dp[r][c] + dp[nr][nc]) % MOD
        return sum(map(sum, dp)) % MOD

複雜度
#

時間 O(mn log(mn))(排序;記憶化 DFS 是 O(mn)),空間 O(mn)。

要特別避免的錯誤
#

  • 用一般的右 / 下 DP:四個方向都可以走。
  • 每個格子自己就是一條路徑,dp 初始值是 1。

面試口說整理
#

雖然四個方向都能走,但路徑嚴格遞增,所以沒有環。dp 是從這格出發的遞增路徑數,等於 1 加上所有比它大的鄰居的 dp。我用記憶化 DFS,或依值由大到小排序後依序算,最後全部加起來。時間 O(mn) 到 O(mn log(mn))。

相關文章

LeetCode 3651: Minimum Cost Path with Teleportations
·2 分鐘
LeetCode Hard Dynamic-Programming Grid-Dp Matrix Array
LeetCode 3651 解題筆記:一層一層算傳送次數;傳送到某格的成本是上一層「值 >= 它的格子」的最小值,排序後用前綴最小值求,再跑一次右 / 下的 Grid DP
LeetCode 2392: Build a Matrix With Conditions
·1 分鐘
LeetCode Hard Graph Topological-Sort Matrix
LeetCode 2392 解題筆記:列條件和欄條件互不影響,各做一次拓撲排序;數字 x 放在列順序和欄順序的位置,任一邊有環就回傳空矩陣
LeetCode 3989: Maximum Consistent Columns in a Grid
·1 分鐘
LeetCode Hard Dynamic-Programming Matrix Array
LeetCode 3989 解題筆記:保留的欄位是一個子序列,只要相鄰的兩欄相容;LIS 型 DP,dp[j] = 以第 j 欄結尾的最長合法序列
LeetCode 488: Zuma Game
·2 分鐘
LeetCode Hard Dynamic-Programming Memoization Breadth-First-Search String Stack
LeetCode 488 解題筆記:board 最多 16 顆、hand 最多 5 顆,把 (board, hand) 整個當狀態做 DFS + 記憶化;只在「同色球前面」和「拆開兩顆同色球」兩種位置插入
LeetCode 1289: Minimum Falling Path Sum II
·3 分鐘
LeetCode Hard Dynamic-Programming Grid-Dp
LeetCode 1289 解題筆記,依照原始 learning note 重新整理
LeetCode 174: Dungeon Game
·3 分鐘
LeetCode Hard Dynamic-Programming Grid-Dp
LeetCode 174 解題筆記,依照原始 learning note 重新整理