132. 分割回文串 II

传送门

题目描述:

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文。

返回符合要求的 最少分割次数 。

思路:最先是套了个三层循环的区间dp板子,果然超时了...

正解:最终结果是要求整个字符串都被划分成回文串,那么我们就没必要用区间dp的模板,

我们只需要求1-i的区间需要划分的最小次数f[i],

转移方程为:

if((1,i)是回文)f[i]=0;

else

     j:1--(i-1)

     if((j+1,i)是回文) 

    f[i]=min(f[i],f[j]+1);

AC代码:

class Solution {
public:
    bool ishuiwen[2005][2005];
    int f[2005];
    int minCut(string s) {
    int n=s.size();
    s.insert(s.begin(),0);
    memset(ishuiwen,1,sizeof(ishuiwen));
    memset(f,0x3f,sizeof(f));
    for(int len=2;len<=n;len++){
        for(int l=1,r=l+len-1;r<=n;l++,r++){//预处理出回文区间
            ishuiwen[l][r]=ishuiwen[l+1][r-1]&&(s[l]==s[r]);
        }
    }
    for(int i=1;i<=n;i++){
        if(ishuiwen[1][i]){
            f[i]=0;
        }else{
            for(int j=1;j<i;j++){
                if(ishuiwen[j+1][i]){
                    f[i]=min(f[i],f[j]+1);
                }
            }
        }
    }
    return f[n];
    }
};

超时代码:

class Solution {
public:
    int dp[2005][2005];
    bool ishuiwen[2005][2005];
    int minCut(string s) {
    memset(dp,0x3f,sizeof(dp));
        memset(ishuiwen,1,sizeof(ishuiwen));
    int n=s.size();
    s.insert(s.begin(),0);
    for(int len=2;len<=n;len++){
        for(int l=1,r=l+len-1;r<=n;l++,r++){
            ishuiwen[l][r]=s[l]==s[r]&&ishuiwen[l+1][r-1];
        }
    }
    for(int len=1;len<=n;len++){
        for(int l=1,r=l+len-1;r<=n;l++,r++){
            if(ishuiwen[l][r]){
                dp[l][r]=0;
            }
            else{
                for(int k=l;k<r;k++){//从中间找拆分位置
                    dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]+1);
                }
            }
        }
    }
    return dp[1][n];
    }
};

 

posted @ 2021-05-11 21:58  cono奇犽哒  阅读(61)  评论(0编辑  收藏  举报