1278. Palindrome Partitioning III
題目網址:https://leetcode.cn/problems/palindrome-partitioning-iii/
題意:給一由小寫字母組成的 string
s
, 和一整數k
。請按下面的要求分割
s
:
- 首先, 你可以將
s
中的部分 char 修改為其他的小寫英文字母- 接著, 你需要把
s
分割成k
個非空且不相交的 substring, 並且每個 substring 都是回文返回以這種方式分割
s
所需修改的最少 char 數目。
Solution 1:
想法:利用 DP
1. 定義狀態:
- 首先, 會在
s
前先加上一個#
, 代表什麼元素都沒有的狀態dp[i][k]
:s[1:i]
切割成k
個回文 substring 的最少修改數2. 得到轉移方程:
dp[i][k] = min(dp[i][k], dp[j - 1][k - 1] + helper(s, j, i))
, for1 ≤ j ≤ i
j
初始化成k
而非1
, 是因為dp[j - 1][k - 1]
指nums[1:(j-1)]
拆成k - 1
個 subarray, 而每個 subarray 至少一個數(j
如果太小,nums[1:(j-1)]
是沒辦法拆成k - 1
個 subarray 的)
➔ 故j
前面至少k - 1
個數, 所以j
的 index 可從k
開始算3. 初始化:
dp[0][0]
:當s = ""
時, 切割成0
個回文 substring 的最少修改數為0
➔dp[0][0] = 0
dp[i][0]
:當s
不為空時,s
不可能透過修改 char 使得自身可以切割成0
個回文 substring, 故將dp[i][0]
設為INT_MAX / 2
代表不可能。設INT_MAX / 2
而非INT_MAX
是為了避免 overflow(題目要求最小, 故初始值要設大)
➔dp[i][0] = INT_MIN / 2
, 其中1 ≤ i ≤ n
dp[0][k]
:當s = ""
時,s
不可能透過修改 char 使得自身可以切割成k
個回文 substring, 故將dp[0][k]
設為INT_MAX / 2
代表不可能
➔dp[0][k] = INT_MIN / 2
, 其中1 ≤ k ≤ k_
class Solution { |
- time:$O(n^3 \cdot k)$ ➔ for loop
- $O(n^2 \cdot k)$:
i
、k
、j
所需的時間分別為 $O(n)$、$O(k)$、$O(n)$ - $O(n)$:
helper()
所需的時間
- $O(n^2 \cdot k)$:
- space:$O(n \cdot k)$ ➔
dp
Solution 2:
想法:改善 Solution 1, 將
helper()
改成用 DP 計算(區間 2 型), 藉此優化時間複雜度1. 定義狀態:
- 首先, 會在
s
前先加上一個#
, 代表什麼元素都沒有的狀態count[i][j]
:s[i:j]
修改成回文所需的最少操作數2. 得到轉移方程:
- 若
s[i] == s[j]
, 則不需修改任何 char
➔count[i][j] = count[i + 1][j - 1]
- 否則, 需要修改其中一個 char
➔count[i] = count[i + 1][j - 1] + 1
3. 初始化:
count[0][0]
:當s = ""
時, 修改成回文所需的最少操作數為0
➔count[0][0] = 0
count[i][i]
:當s[i:j]
中只有一個 char 時, 修改成回文所需的最少操作數為0
➔count[i][i] = 0
class Solution { |
- time:$O(n^2 \cdot k)$ ➔ for loop
- space:$O(n^2 + n \cdot k)$ ➔
count
、dp
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論