manacher(马拉车)算法———最长字串问题

manacher算法

通过增大空间复杂度来减少找字串的时间,使之降为o(n)
具体方法可见
(漫画)如何找到字符串中的最长回文子串?

小明的字符串问题
描述

小明刚刚做完了回文电话号码的问题,觉得意犹未尽,开始思考一个升级版的问题:随便给一个长度不超过1000的字符串s,一定可以找到很多回文子串,例如s=“babad”,可以找到"bab"和"aba",那么在这些回文子串中,最长的那个子串是什么呢?请你写一个程序帮小明回答这个问题。

如果有多个相同长度的回文子串,请输出最先出现的那个。
输入
一个长度不超过1000的字符串,字符串保证不含空格。

输出
最早出现的、最长的那个回文子串

输入样例 1

cbbd
输出样例 1

bb

此为题解,c语言方案

#include <stdio.h>
#include <string.h>
#define min(a,b) a>b? b:a
void find_palindrome(char *s, char *r)
{
  char t[2500]={0},len[2500]={0};//len[]->长度;t->用于处理的string
  t[0]='*';t[1]='#';
  for(int i=0;s[i]!=0;i++)//预处理 +‘#’
  {
  t[2*i+2]=s[i];
  t[2*i+3]='#' ;
  }
  int mx=0,i,mid=0,ans=0,x;
  for( i=1;t[i]!=0;i++)
  {
    if(i<mx)
    len[i]= min(len[mid*2-i],mx-i);
    else len[i]=1;
    while(t[i-len[i]]==t[i+len[i]])
    len[i]++;
    if(len[i]+i>mx)
    {
       mx=len[i]+i;
       mid=i;
    }
    /*!!注意mid不是最大的中间位置!!!
      是当前的可容纳最多元素的字串的中间位置
      mx边界 need choose the big */
    if(len[i]>ans)
    {
        ans=len[i];
	    x=i;//x——>最大子串的位置
    }
  }  //ans->the length of the longest string 
    // you can try a example like abba->*a#b#b#a#
  //or   aba->#a#b#a#
  ans--;//-1就将半径变为长度
  
  int j=0;
  for(i=x-ans;i<=x+ans;i++)//mid -〉 t[]中的位置
   {
       if(t[i]!='#'&&t[i]!='*')
        {
          r[j]=t[i];
          j++;
        }
   }
}//题目要求输出最长字串
int main()
{
    char s[1001]= {0}, r[1001] = {0};
    scanf("%s", s);
    find_palindrome(s, r);
    printf("%s", r);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值