分割回文

字符串分割

最少分割

问题描述

给定一个字符串,返回把str全部切割成回文串的最少切割数。

输入输出
输入:

ABCBAEEE

输出:

1

分割一次ABCBA与EEE

常规思路

dp[i][j]=k表示从i=>j部分最少分割,那么最终所求为dp[0][len-1]
求解过程为区间长度从2=》len 即先求解小区间问题。
每一次求解过程将原区间分为两部分 左右最小分割数之和的最小值即为所求
(若区间本身为回文串=》dp=0)

时间复杂度为O(N3) 复杂度较高

优化思路

dp[i]=k表示前面i个字符的串的最少分割数
round[i][j]=1表示i=>j为回文串;=0表示不是回文串
计算dp[i]时,j= i=>0 分别研究其末尾【j,i】是否为回文串。
方法为 str[i]==str[j] && (i-j<=1 || round[j+1][i-1]) 即内部为回文串
若末尾为回文串,那么dp[i]=min(dp[i],dp[j-1]+1) 即末尾分割数为0

代码实现

#include<iostream>
#include<string>
#include<vector>
#include<limits.h>
using namespace std;
int main()
{
    string str1;
    cin>>str1;
    int len=str1.size();
    vector<vector<int>> dp(len,vector<int>(len,0));  //dp[i][j]=1表示i=j是回文串
    vector<int> dp1(len+1,INT_MAX);//dp1[i]=k表示前i个数字的最少分割
    dp1[0]=-1;
    for(int i=0;i<len;i++)
    {
        //计算dp1[i+1]
        for(int j=i;j>=0;j--)  //研究末尾区间是否为回文串
        {
            if(str1[j]==str1[i] && (i-j<=1 || dp[j+1][i-1]==1))//是回文串
            {
                dp[j][i]=1;
                dp1[i+1]=min(dp1[i+1],dp1[j]+1);//若末尾为回文串 直接前面部分也就是0=》j-1的分数+1
            }
        }

    }

    cout<<dp1[len]<<endl;

}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页