21 3 8 力扣每日刷題 分割回文串

2021-10-21 10:18:43 字數 1585 閱讀 9131

給你乙個字串 s,請你將 s 分割成一些子串,使每個子串都是回文。

返回符合要求的 最少分割次數 。

示例 1:

輸入:s =

"aab"

輸出:1

解釋:只需一次分割就可將 s 分割成 [

"aa","b"

] 這樣兩個回文子串。

示例 2:

輸入:s =

"a"輸出:0

示例 3:

輸入:s =

"ab"

輸出:1

1 <= s.length <= 2000

s 僅由小寫英文本母組成

方法一:動態規劃

思路與演算法

設 f[i]f[i] 表示字串的字首 s[0..i]s[0..i] 的最少分割次數。要想得出 f[i]f[i] 的值,我們可以考慮列舉 s[0..i]s[0..i] 分割出的最後乙個回文串,這樣我們就可以寫出狀態轉移方程:

f[i]

= 0≤jmin +1,其中 s[j+1..i] 是乙個回文串

​ 即我們列舉最後乙個回文串的起始位置 j+1j+1,保證 s[j+1..i]s[j+1..i] 是乙個回文串,那麼 f[i]f[i] 就可以從 f[j]f[j] 轉移而來,附加 11 次額外的分割次數。

注意到上面的狀態轉移方程中,我們還少考慮了一種情況,即 s[0..i]s[0..i] 本身就是乙個回文串。此時其不需要進行任何分割,即:

f[i]

= 0f[i]

=0那麼我們如何知道 s[j+1..i]s[j+1..i] 或者 s[0..i]s[0..i] 是否為回文串呢?我們可以使用與「131. 分割回文串的官方題解」中相同的預處理方法,將字串 ss 的每個子串是否為回文串預先計算出來,即:

g(i,j)

=設 g(i, j)g(i,j) 表示 s[i..j]s[i..j] 是否為回文串,那麼有狀態轉移方程:

其中 ∧ 表示邏輯與運算,即 s[i..j]s[i..j] 為回文串,當且僅當其為空串(i>ji>j),其長度為 11(i=ji=j),或者首尾字元相同且 s[i+1..j-1]s[i+1..j−1] 為回文串。

這樣一來,我們只需要 o(1)o(1) 的時間就可以判斷任意 s[i..j]s[i..j] 是否為回文串了。通過動態規劃計算出所有的 ff 值之後,最終的答案即為 f[n-1]f[n−1],其中 nn 是字串 ss 的長度。

**

class

solution

} vector<

int>

f(n, int_max)

;for

(int i =

0; i < n;

++i)

else}}

}return f[n -1]

;}};

複雜度分析

時間複雜度:o(n^2)其中 n 是字串 s 的長度。預處理計算 g 和動態規劃計算 ff 的時間複雜度均為 o(n^2)。

空間複雜度:o(n^2),陣列 g 需要使用 o(n^2)的空間,陣列 f 需要使用 o(n^2)的空間。

今天也是cv的一天。

每日刷題 分割回文串II

給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。返回符合要求的最少分割次數。示例 輸入 aab 輸出 1 解釋 進行一次分割就可將 s 分割成 aa b 這樣兩個回文子串。解法一 沿用分割會文串 的方法,將所有可能的結果列舉出來,然後選擇長度最小的即可。親測,超時。解法二 動態規劃。...

力扣每日一題 131 分割回文串

解題思路 解題 解題感悟 難度 中等 題目 給你乙個字串 s,請你將 s 分割成一些子串,使每個子串都是 回文串 返回 s 所有可能的分割方案。回文串 是正著讀和反著讀都一樣的字串。輸入 s aab 輸出 a a b aa b 輸入 s a 輸出 a 力扣 leetcode 鏈結 首先,回文串是從前...

力扣131 分割回文串

題目 給定乙個字串 s,將 s 分割成一些子串,使每個子串都是回文串。返回 s 所有可能的分割方案。示例 輸入 aab 輸出 aa b a a b 分析 有點向之前求所有子串問題,採用dp動態規劃演算法,只是多加上了判斷是否為回文串,在 aab 一例中可以依次分析如下分割是否滿足回文串特性 a a ...