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

LeetCode 1745: Palindrome Partitioning IV

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

基本資料
#

難易度: hard 第一次嘗試:2026-06-27

  • 提交紀錄:Wrong Answer ×2 → Accepted(暴力)→ Accepted ×2(回文表)

解題思路
#

  1. 用區間 DP 建 is_pal[i][j]:s[i] == s[j],而且裡面那段是回文(長度 <= 2 時直接成立)。依長度由短到長填。
  2. 枚舉兩個切點:第一段 [0, i]、第二段 [i + 1, j]、第三段 [j + 1, n - 1],三段都非空:0 <= i < j < n - 1。

我的嘗試
#

前三版是直接切字串、用 s == s[::-1] 檢查,O(n^3)。兩次 WA 都是切點的範圍:

版本問題
第一版跳過了 j == n - 1(j 是第三段的起點),漏掉第三段只有一個字元的情況。例如 s = "aab":"a" + "a" + "b",答案是 True,回傳 False
第二版拿掉那個限制,但 j 從 i 開始,第二段可以是空的。例如 s = "abab":"aba" + "" + "b" 被當成合法,答案是 False,回傳 True
第三版 ACj 從 i + 1 開始,但切字串的暴力版本跑了 8 秒

之後改成先建回文表,O(n^2)。

正確解法
#

class Solution:
    def checkPartitioning(self, s: str) -> bool:
        n = len(s)
        is_pal = [[False] * n for _ in range(n)]
        for i in range(n - 1, -1, -1):
            for j in range(i, n):
                is_pal[i][j] = s[i] == s[j] and (j - i < 2 or is_pal[i + 1][j - 1])

        for i in range(n - 2):                     # 第一段 [0, i]
            if not is_pal[0][i]:
                continue
            for j in range(i + 1, n - 1):          # 第二段 [i+1, j],第三段 [j+1, n-1]
                if is_pal[i + 1][j] and is_pal[j + 1][n - 1]:
                    return True
        return False

複雜度
#

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

要特別避免的錯誤
#

  • 三段都要非空,切點的範圍要寫清楚。
  • 每次都切字串檢查回文:O(n^3)。

面試口說整理
#

我先用區間 DP 建回文表,s[i] 等於 s[j] 而且裡面是回文就是回文。接著枚舉兩個切點,確保三段都非空,三段都是回文就回傳 True。建表和枚舉都是 O(n^2)。

相關文章

LeetCode 312: Burst Balloons
·1 分鐘
LeetCode Hard Dynamic-Programming Interval-Dp Array
LeetCode 312 解題筆記:枚舉區間 (i, j) 裡「最後一個」戳破的氣球 k,這時它的鄰居就是 i 和 j,左右兩邊的子問題互相獨立
LeetCode 3906: Count Good Integers on a Grid Path
·2 分鐘
LeetCode Hard Dynamic-Programming Digit-Dp
LeetCode 3906 解題筆記:範圍到 9 × 10^15,不能逐一檢查;數位 DP 同時帶上下界兩個 tight,路徑上的格子要非遞減,狀態多記「路徑上前一個數字」
LeetCode 1537: Get the Maximum Score
·2 分鐘
LeetCode Hard Dynamic-Programming Two-Pointers Greedy Array
LeetCode 1537 解題筆記:兩個排序陣列只在共同的值可以換路;雙指針合併,兩條路各自累加,遇到共同的值時兩邊都取較大的那個再加上它
LeetCode 3816: Lexicographically Smallest String After Deleting Duplicate Characters
·1 分鐘
LeetCode Hard Stack Monotonic-Stack Greedy String
LeetCode 3816 解題筆記:單調棧,頂端比較大而且還有別的副本就刪;最後把尾巴重複的也刪掉,因為前綴一定比較小
LeetCode 2781: Length of the Longest Valid Substring
·2 分鐘
LeetCode Hard Sliding-Window Hash-Table String Trie
LeetCode 2781 解題筆記:禁字最長只有 10,每個右端只檢查最後 10 個字元組成的後綴;找到禁字就把左端推到它後面,要找最短的那個(最靠右的起點)
LeetCode 1458: Max Dot Product of Two Subsequences
·1 分鐘
LeetCode Hard Dynamic-Programming Longest-Common-Subsequence Array
LeetCode 1458 解題筆記:兩個前綴的 DP;dp[i][j] 可以配對 nums1[i]、nums2[j](接在 dp[i-1][j-1] 後面或自己開頭),或跳過其中一個