不重叠回文子字符串的最大数目
难度:
标签:
题目描述
代码结果
运行时间: 43 ms, 内存: 16.1 MB
/*
* 思路:
* 1. 仍然使用动态规划思想,但结合Java Stream处理。
* 2. dp数组的定义和java解法一样。
* 3. 使用Stream和Lambda表达式简化代码。
*/
import java.util.stream.IntStream;
public class Solution {
public int maxPalindromes(String s, int k) {
int n = s.length();
int[] dp = new int[n + 1];
IntStream.range(0, n).forEach(i -> {
dp[i + 1] = dp[i];
IntStream.rangeClosed(0, i - k + 1).filter(j -> isPalindrome(s, j, i)).forEach(j -> dp[i + 1] = Math.max(dp[i + 1], dp[j] + 1));
});
return dp[n];
}
private boolean isPalindrome(String s, int left, int right) {
while (left < right) {
if (s.charAt(left++) != s.charAt(right--)) {
return false;
}
}
return true;
}
}
解释
方法:
这个题解采用了动态规划的方法与中心扩展算法的结合。对于每个中心点(字符或两字符之间),算法尝试向两边扩展以找到可能的回文串。动态规划数组 `f` 中,`f[i]` 表示考虑到字符串的前 `i` 个字符,能够形成的最大不重叠的回文串个数。每次找到一个合法的回文串后(长度至少为 `k`),就尝试更新 `f[r+1]`(即扩展到的右边界的下一个位置)。这样,当遍历完成所有可能的中心点后,`f[n]` 将包含整个字符串的最大不重叠回文子字符串数目。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在找到一个长度至少为k的回文串后,就不再继续扩展,直接break退出循环?
▷🦆
在动态规划数组f中,为什么要初始化f[l+1]为max(f[l+1], f[l])?这样的初始化有什么作用?
▷🦆
动态规划解法中,如何确保更新的回文子串是不重叠的?
▷🦆
在中心扩展算法中,为什么要选择2n-1个中心点?具体是如何确定每个中心点的左右边界l和r的?
▷