一、Problem
段式迴文 其實與 一般迴文 類似,只不過是最小的單位是 一段字符 而不是 單個字母。
舉個例子,對於一般迴文 “abcba” 是迴文,而 “volvo” 不是,但如果我們把 “volvo” 分爲 “vo”、“l”、“vo” 三段,則可以認爲 “(vo)(l)(vo)” 是段式迴文(分爲 3 段)。
給你一個字符串 text,在確保它滿足段式迴文的前提下,請你返回 段 的 最大數量 k。
如果段的最大數量爲 k,那麼存在滿足以下條件的 a_1, a_2, …, a_k:
每個 a_i 都是一個非空字符串;
將這些字符串首位相連的結果 a_1 + a_2 + … + a_k 和原始字符串 text 相同;
對於所有1 <= i <= k,都有 a_i = a_{k+1 - i}。
輸入:text = "ghiabcdefhelloadamhelloabcdefghi"
輸出:7
解釋:我們可以把字符串拆分成 "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)"。
提示:
text 僅由小寫英文字符組成。
1 <= text.length <= 1000
二、Solution
方法一:記憶化搜索
- 定義狀態:
- 表示字符串 中段式迴文串的最大長度。
- 思考初始化:
- 表示單個字符的段式迴文長度爲 1
- 思考狀態轉移方程:
- 如果 ,
- 思考輸出:
class Solution {
int n, f[][];
String str;
int dfs(int s, int e) {
if (s > e)
return 0;
if (s == e)
return 1;
if (f[s][e] != 0)
return f[s][e];
int len = 1;
for (int l = 1; l <= (e-s+1)/2; l++) {
String beg = str.substring(s, s+l), end = str.substring(e-l+1, e+1);
if (beg.equals(end)) {
len = Math.max(len, dfs(s+l, e-l)+2);
}
}
return f[s][e] = len;
}
public int longestDecomposition(String text) {
str = text;
n = str.length();
f = new int[n][n];
f[0][0] = 1;
dfs(0, n-1);
return f[0][n-1];
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,