1246. Palindrome Removal
題目網址:https://leetcode.cn/problems/palindrome-removal/
題意:給一整數 array
arr, 每次操作你都可以刪除一個回文 subarrayarr[i], arr[i+1], ..., arr[j](i ≤ j)。每當你刪掉一個 subarray, 其右側元素會向前填補空位。
計算從
arr中刪除所有數字所需的最少操作數。

Solution:
想法:利用 DP, 當找不出突破口時, 試著從最後一個元素下手
1. 定義狀態:
- 首先, 會在
arr前先加上一個0, 代表什麼元素都沒有的狀態dp[i][j]:arr[i:j]刪除所有數字的最小操作數2. 得到轉移方程:
要在
arr[i:j]中找回文, 就先判斷arr[j]要和哪個數消除
- 若
arr[j]和arr[k]相等時, 則一同消除, 其中i ≤ k ≤ j
➔dp[i][j] = dp[i + 1][k] + dp[k + 1][j - 1]- 當
dp[k + 1][j - 1]不為空區間時, 則arr[k]、arr[j]可以被算在子區間的最後一次刪除中
- e.g.
arr = [1, 2, 3, 1]➔[0, 1, 2, 3, 1]
- 其中
dp[2][3] = 2, 要刪除[2, 3]需操作2次- 由於
arr[1] == arr[4], 可以先刪除子區間中的2, 此時arr變成[1,3,1]為回文, 故只要再刪一次狀態轉移方程:
dp[i][j] = min(dp[i][j], dp[i][k - 1] + max(1, dp[k + 1][j - 1]))max(1, dp[k + 1][j - 1])是因為k + 1可能會越界。若越界, 根據dp[i][j]的定義,dp[k + 1][j - 1]為空區間, 故設為0。但此時要消除dp[k][j]的代價應為1, 而不是0
- 當
dp[k + 1][j - 1] == 0時, 取1- 當
dp[k + 1][j - 1] != 0時, 取dp[k + 1][j - 1]
3. 初始化:
dp[0][0]:為空區間, 刪除所有數字的最小操作數0dp[i][i]:當區間中只有一個數時, 刪除所有數字的最小操作數1。其中,1 ≤ i ≤ n4. 注意事項:
dp的長度之所以要開n + 2而非n + 1, 是因為i ≤ k ≤ j
➔dp[k + 1][j - 1]中的k + 1最多是n + 1, 故長度開n + 2
class Solution { |
- time:$O(n^3)$ ➔ for loop
- space:$O(n^2)$ ➔
dp
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論
