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 ≤ ij初始化成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] = 0dp[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 ≤ ndp[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] + 13. 初始化:
count[0][0]:當s = ""時, 修改成回文所需的最少操作數為0
➔count[0][0] = 0count[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!
評論