一、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];
}
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,