笔试面试题(8)---回文子串

本文介绍了几种求解回文串问题的有效算法,包括线性的中心扩展法和动态规划方法,并提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、验证整个字符串是不是回文(最简单的了)

      直接验证或递归验证都可以....

2、求连续的回文子串,如:abdadbx,则回文子串就是bdadb

      整个有一个最优的算法为:“中心法求最长回文子串”(线性复杂度),具体的博客:http://www.cnblogs.com/wuyiqi/archive/2012/06/25/2561063.html写的真好!

    

#include<cstdio>
#include<cstring>
const int M = 110010*2;
char str[M];//start from index 1
int p[M];
char s[M];
int n;
void checkmax(int &ans,int b){
    if(b>ans) ans=b;
}
inline int min(int a,int b){
    return a<b?a:b;
}
void kp(){
    int i;
    int mx = 0;
    int id;
    for(i=1; i<n; i++){
        if( mx > i )
            p[i] = min( p[2*id-i], p[id]+id-i );
        else
            p[i] = 1;
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++) ;
        if( p[i] + i > mx ) {
            mx = p[i] + i;
            id = i;
        }
    }
}
void pre()
{
    int i,j,k;
    n = strlen(s);
    str[0] = '$';
    str[1] = '#';
    for(i=0;i<n;i++)
    {
        str[i*2 + 2] = s[i];
        str[i*2 + 3] = '#';
    }
    n = n*2 + 2;
    str[n] = 0;
}

void pt()
{
    int i;
    int ans = 0;
    for(i=0;i<n;i++)
        checkmax(ans, p[i]);
    printf("%d\n", ans-1);
}

int main()
{
    int T,_=0;
    while( scanf("%s", s) !=EOF )
    {
        pre();
        kp();
        pt();
    }
    return 0;
}


 

     如果用动态规划的用O(n^2)吧

#include <iostream>
#include <cmath>
using namespace std;
#define MAXLEN 1000
int maxlen[MAXLEN][MAXLEN];
int LongestLen(char str[], int slen)

{
    int i, j, len;
    for (i = 0; i < slen; i++)
    {

        maxlen[i][i] = 1;
    }
    for (len = 1; len < slen; len++)
    {
        for (i = 0; i <= slen - len; i++)
        {
            j = i + len;
            if (str[i] == str[j])
            {
                if (i + 1 > j - 1)
                {
                    maxlen[i][j] = 2;
                }
                else
                {
                    maxlen[i][j] = 2 + maxlen[i + 1][j - 1];
                }
            }
            else
            {
                maxlen[i][j] = maxlen[i + 1][j]> maxlen[i][j - 1]?  maxlen[i + 1][j]:maxlen[i][j - 1];
            }
        }
    }
    return maxlen[0][slen - 1];
}

int main()
{
    char str[1000];
    cin>>str;
    int ans=LongestLen(str,strlen(str));
    cout<<ans<<endl;
    return 0;
}


 3、如果要可以不连续的回文子串,只能用DP了,中心扩展法是求不了的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值