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

LeetCode 1616: Split Two Strings to Make Palindrome

·2 分鐘· ·
LeetCode Medium Two-Pointers String Greedy
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-01-24

  • 提交紀錄:WA → TLE ×2 → WA → AC → WA → AC

解題思路
#

在同一個位置把 a 和 b 切開,檢查 a 前綴 + b 後綴 或 b 前綴 + a 後綴 能不能是回文。

以 a 前綴 + b 後綴 為例,用對撞指針:左指針在 a 上往右、右指針在 b 上往左,只要 a[left] == b[right] 就繼續往內。這段外側一定能用「a 的前綴配 b 的後綴」湊成回文。

停下來時,中間還沒配好的 [left, right] 這段,整段只能來自同一個字串(切點一定落在這段裡),所以它必須是 a[left..right] 或 b[left..right] 自己就是回文。

另一個方向 b 前綴 + a 後綴 也要檢查一次。

我的嘗試
#

版本問題
第一版 WA只檢查了 a 前綴 + b 後綴 一個方向,切點也只到 n - 1。例如 a = "aa"、b = "ab":取整個 a 就是回文,答案是 True,這版回傳 False
兩次 TLE補上另一個方向、切點改成 0..n,但每個切點都重新組字串檢查回文,O(n^2)
第四版 WA改成貪心比對 + 檢查中間段,但 is_palindrome 裡寫成 i -= 1、j += 1,指針往外走,直接越界
第六版 WA最後一行寫成 check(a, b) or check(a, b),第二個應該是 check(b, a)。例如 a = "aaab"、b = "babb":b 前綴 "ba" 加 a 後綴 "ab" 是 "baab",答案是 True,這版只檢查了一個方向,回傳 False

正確解法
#

class Solution:
    def checkPalindromeFormation(self, a: str, b: str) -> bool:
        def is_palindrome(s: str, i: int, j: int) -> bool:
            while i < j:
                if s[i] != s[j]:
                    return False
                i += 1
                j -= 1
            return True

        def check(x: str, y: str) -> bool:            # x 的前綴 + y 的後綴
            left, right = 0, len(x) - 1
            while left < right and x[left] == y[right]:
                left += 1
                right -= 1
            return is_palindrome(x, left, right) or is_palindrome(y, left, right)

        return check(a, b) or check(b, a)

複雜度
#

時間 O(n),空間 O(1)。

要特別避免的錯誤
#

  • 只檢查一個方向。
  • 每個切點都重新組字串:O(n^2)。
  • 判斷回文時指針往外走。
  • 同一個函式呼叫兩次卻沒有交換參數。

面試口說整理
#

以 a 的前綴加 b 的後綴為例,我用對撞指針從外往內,只要 a[left] 等於 b[right] 就繼續。停下來時,中間剩下的那段只能整段來自同一個字串,所以檢查它在 a 或 b 裡是不是回文。另一個方向交換 a、b 再檢查一次,時間 O(n)。

相關文章

LeetCode 1750: Minimum Length of String After Deleting Similar Ends
·1 分鐘
LeetCode Medium Two-Pointers String
LeetCode 1750 解題筆記:兩端字元相同時,各自把同一段相同字元全部吃掉;整段都是同一個字元時可以刪光
LeetCode 948: Bag of Tokens
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 948 解題筆記:排序後,用最小的 token 換分數、用最大的 token 換能量;只有分數 > 0 才能換能量,換不了就停
LeetCode 2131: Longest Palindrome by Concatenating Two Letter Words
·1 分鐘
LeetCode Medium Greedy Hash-Table String Counting
LeetCode 2131 解題筆記:每個字跟它的反轉配成一對放兩邊;本身是回文的字也能兩兩配對,只有剩下的一個能放正中間
LeetCode 611: Valid Triangle Number
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search Greedy
LeetCode 611 解題筆記:排序後固定最長邊 k,左右指針找兩短邊:和夠大時中間的都可以,一次加 j - i 個
LeetCode 402: Remove K Digits
·1 分鐘
LeetCode Medium String Stack Greedy Monotonic-Stack
LeetCode 402 解題筆記:單調遞增 stack,遇到比頂端小的數字就把頂端刪掉(還有 k 次可刪時),最後去掉前導零
LeetCode 151: Reverse Words in a String
·1 分鐘
LeetCode Medium Two-Pointers String
LeetCode 151 解題筆記:split() 不帶參數會把連續空白當成一個分隔,也會去掉頭尾空白;反轉後用一個空白接起來