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

LeetCode 3989: Maximum Consistent Columns in a Grid

·1 分鐘· ·
LeetCode Hard Dynamic-Programming Matrix Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-07-13

  • 提交紀錄:Accepted ×2(記憶化 → LIS 型迴圈)

解題思路
#

保留下來的欄位維持原本順序,是欄位的子序列。條件只看相鄰的兩欄:每一列的差都 <= limit。

這跟 LIS 一樣:dp[j] = 以第 j 欄結尾、最多能保留幾欄。

dp[j] = 1 + max(dp[i]),i < j 而且第 i 欄和第 j 欄相容

檢查兩欄是否相容要看 m 列,所以總共 O(n^2 · m)。

我的解法
#

class Solution:
    def maxConsistentColumns(self, grid: List[List[int]], limit: int) -> int:
        m, n = len(grid), len(grid[0])

        def compatible(a: int, b: int) -> bool:
            return all(abs(grid[r][b] - grid[r][a]) <= limit for r in range(m))

        dp = [1] * n                               # dp[j]:以第 j 欄結尾
        for j in range(n):
            for i in range(j):
                if dp[i] + 1 > dp[j] and compatible(i, j):
                    dp[j] = dp[i] + 1
        return max(dp)

先比較 dp[i] + 1 > dp[j] 再檢查相容,可以省掉一些不會更新答案的檢查。

我第一次 AC 用的是 dp(cur, prev) 的記憶化(目前看到第 cur 欄、上一個保留的是 prev),狀態數也是 O(n^2),但多了遞迴的開銷。

複雜度
#

時間 O(n^2 · m),空間 O(n)。

要特別避免的錯誤
#

  • 至少要保留一欄,dp 初始值是 1。
  • 條件只看保留下來後相鄰的兩欄,不是原本相鄰的兩欄。

面試口說整理
#

保留的欄位是一個子序列,而條件只看保留後相鄰的兩欄,所以跟 LIS 一樣:dp[j] 是以第 j 欄結尾最多能保留幾欄,枚舉前一個保留的欄位 i,兩欄每一列的差都不超過 limit 就能接上。時間 O(n^2 · m)。

相關文章

LeetCode 3651: Minimum Cost Path with Teleportations
·2 分鐘
LeetCode Hard Dynamic-Programming Grid-Dp Matrix Array
LeetCode 3651 解題筆記:一層一層算傳送次數;傳送到某格的成本是上一層「值 >= 它的格子」的最小值,排序後用前綴最小值求,再跑一次右 / 下的 Grid DP
LeetCode 1402: Reducing Dishes
·1 分鐘
LeetCode Hard Dynamic-Programming Greedy Sorting Array
LeetCode 1402 解題筆記:排序後從滿意度大的開始選;每多選一道放在最前面,前面選的都往後一格,總和增加「目前選的滿意度總和」,總和是正的就繼續選
LeetCode 1526: Minimum Number of Increments on Subarrays to Form a Target Array
·1 分鐘
LeetCode Hard Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 1526 解題筆記:從左往右看,每次比前一個高,多出來的高度都要新開那麼多次操作;變矮的部分可以沿用之前的操作
LeetCode 1335: Minimum Difficulty of a Job Schedule
·1 分鐘
LeetCode Hard Dynamic-Programming Interval-Dp Array
LeetCode 1335 解題筆記:切成 d 段的分割 DP;dp(i, k) = 從第 i 個工作開始、剩 k 天的最小難度,枚舉今天做到哪裡,邊枚舉邊更新今天的最大難度
LeetCode 312: Burst Balloons
·1 分鐘
LeetCode Hard Dynamic-Programming Interval-Dp Array
LeetCode 312 解題筆記:枚舉區間 (i, j) 裡「最後一個」戳破的氣球 k,這時它的鄰居就是 i 和 j,左右兩邊的子問題互相獨立
LeetCode 1537: Get the Maximum Score
·2 分鐘
LeetCode Hard Dynamic-Programming Two-Pointers Greedy Array
LeetCode 1537 解題筆記:兩個排序陣列只在共同的值可以換路;雙指針合併,兩條路各自累加,遇到共同的值時兩邊都取較大的那個再加上它