剑指 Offer II 094. 最少回文分割
给定一个字符串 s,请将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的 最少分割次数 。
示例 1:
输入:s = “aab”
输出:1
解释:只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。
示例 2:
输入:s = “a”
输出:0
示例 3:
输入:s = “ab”
输出:1
提示:
1 <= s.length <= 2000
s 仅由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/omKAoA
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
1、寻找状态转移方程。对于长度为i + 1的字符串(最后索引为i),假设f(i)为分割的最小次数,那么我们从0到i中找到一个索引 j 使得 j 到 i 为回文串,那么f(i) = f(j - 1) + 1,我们可能可以找到不止一个 j ,那么我们可以通过遍历找到最小的f(j - 1)从而得到最小的f(i)。
2、现在变成如何构建dp数组以及如何确定 j 到 i 是回文串的问题了。由于第一个索引0是固定的,我们只需要移动 i 即可,dp数组是一维数组,从0到 i 的dp都可能要用到,所以dp长度是s.length()。
3、如何判断某段连续子串是回文串可以用
https://blog.csdn.net/weixin_43942435/article/details/123388977的方法;这里参考剑指offer的题解进行改进,少进行一次遍历填充数组操作。
4、在求解dp数组的过程需要注意:如果flag[0][i]是false,需要先对dp[i]赋值i,再进行循环寻找 j ,因为如果没有 j 满足 j 到 i 是回文串就需要分割 i 次。
题解(Java)
class Solution {
public int minCut(String s) {