马拉车用于解决最长回文子串问题,重点是子串,而不是子序列,时间复杂度为O(n)。

解释一下变量的意义:

Len[i]数组去存第i个位置到mx位置的长度

id记录上一次操作的位置(这个操作可以看模板)

mx标记上一次的最长子串的最右端

模板:

 1 void init()  //这个是用来处理字符串的
2 {
3 memset(str,0,sizeof(str));
4 int k=0;
5 str[k++]='$';
6 for(int i=0;i<len;++i)
7 str[k++]='#',str[k++]=s[i];
8 str[k++]='#';
9 len=k;
10 }
11 int manacher() //求最长回文子串
12 {
13 Len[0]=0;
14 int sum=0;
15 int id,mx=0;
16 for(int i=1;i<len;++i)
17 {
18 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]);
19 else Len[i]=1;
20 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++;
21 if(Len[i]+i>mx)
22 {
23 mx=Len[i]+i;
24 id=i;
25 sum=max(sum,Len[i]);
26 }
27 }
28 return (sum-1);
29 }

当我们要求的以第i个字符为回文字符串的中心的时候,如果i>=mx这个时候没法优化,就是判断(i-1)==(i+1)、(i-2)==(i+2)....一直这样找

看代码就是进行19行、再进行20行

如果i<mx的时候,这个时候

这个时候看一道模板题:

Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?"


A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not.



The students recognized that this is a classical problem but couldn't come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I've a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I've an even better algorithm!".



If you think you know Andy's final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

Input

Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity).

Output

For each test case in the input print the test case number and the length of the largest palindrome.

Sample Input

abcbabcbabcba
abacacbaaaab
END

Sample Output

Case 1: 13
Case 2: 6

这个时候要注意

不知道是这里memset(Len,0,sizeof(Len)); 导致的超时

还是

 1 void init()
2 {
3 memset(str,0,sizeof(str));
4 int k=0;
5 str[k++]='$';
6 for(int i=0;i<strlen(s);++i) 这个strlen导致的
7 str[k++]='#',str[k++]=s[i];
8 str[k++]='#';
9 len=k;
10 }

正确代码:

 1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<set>
6 using namespace std;
7 const int maxn=3000005;
8 const int INF=0x3f3f3f3f;
9 const int mod=998244353;
10 char str[maxn],s[maxn];
11 int len,Len[maxn];
12 void init()
13 {
14 memset(str,0,sizeof(str));
15 int k=0;
16 str[k++]='$';
17 for(int i=0;i<len;++i)
18 str[k++]='#',str[k++]=s[i];
19 str[k++]='#';
20 len=k;
21 }
22 int manacher()
23 {
24 Len[0]=0;
25 int sum=0;
26 int id,mx=0;
27 for(int i=1;i<len;++i)
28 {
29 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]);
30 else Len[i]=1;
31 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++;
32 if(Len[i]+i>mx)
33 {
34 mx=Len[i]+i;
35 id=i;
36 sum=max(sum,Len[i]);
37 }
38 }
39 return (sum-1);
40 }
41 int main()
42 {
43 int t=0;
44 while(~scanf("%s",s))
45 {
46 //memset(Len,0,sizeof(Len));
47 if(strcmp("END",s)==0) break;
48 len=strlen(s);
49 init();
50 printf("Case %d: %d\n",++t,manacher());
51 }
52 return 0;
53 }

Manacher算法 & Palindrome的更多相关文章

  1. Palindrome(poj3974)(manacher算法)

    http://poj.org/problem?id=3974 Palindrome Time Limit: 15000MSMemory Limit: 65536K Total Submissions: ...

  2. Palindrome(最长回文串manacher算法)O(n)

     Palindrome Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  3. Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp

    题目链接: http://codeforces.com/problemset/problem/7/D D. Palindrome Degree time limit per test1 secondm ...

  4. 利用Manacher算法寻找字符串中的最长回文序列(palindrome)

    寻找字符串中的最长回文序列和所有回文序列(正向和反向一样的序列,如aba,abba等)算是挺早以前提出的算法问题了,最近再刷Leetcode算法题的时候遇到了一个(题目),所以就顺便写下. 如果用正反 ...

  5. POJ3974 Palindrome (manacher算法)

    题目大意就是说在给定的字符串里找出一个长度最大的回文子串. 才开始接触到manacher,不过这个算法的确很强大,这里转载了一篇有关manacher算法的讲解,可以去看看:地址 神器: #includ ...

  6. POJ 3974 Palindrome 字符串 Manacher算法

    http://poj.org/problem?id=3974 模板题,Manacher算法主要利用了已匹配回文串的对称性,对前面已匹配的回文串进行利用,使时间复杂度从O(n^2)变为O(n). htt ...

  7. 【Manacher算法】poj3974 Palindrome

    Manacher算法教程:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824 模板题,Code 附带注释: #include<cs ...

  8. hdu 3068 最长回文 manacher算法(视频)

    感悟: 首先我要Orz一下qsc,我在网上很难找到关于acm的教学视频,但偶然发现了这个,感觉做的很好,链接:戳戳戳 感觉这种花费自己时间去教别人的人真的很伟大. manacher算法把所有的回文都变 ...

  9. HDU3068 最长回文 Manacher算法

    Manacher算法是O(n)求最长回文子串的算法,其原理很多别的博客都有介绍,代码用的是clj模板里的,写的确实是异常的简洁,现在的我只能理解个大概,下面这个网址的介绍比较接近于这个模板,以后再好好 ...

随机推荐

  1. 基于 OpenMP 的奇偶排序算法的实现

    代码: #include <omp.h> #include <iostream> #include <cstdlib> #include <ctime> ...

  2. Python运维自动化psutil 模块详解(超级详细)

    psutil 模块 参考官方文档:https://pypi.org/project/psutil/ 一.psutil简介 psutil是一个开源且跨平台(http://code.google.com/ ...

  3. 【Shell】使用awk sed获取一行内容的两个值

    突然有需求需要一个脚本,同时获取到每一行数据的两个值,下面做了一个例子模板,仅供记录参考 cat test.txt  id=1,name=zclinux1 id=2,name=zclinux2 id= ...

  4. 网件wndr4300 ttl连接

    路由成砖而还能进入cfe或uboot等情况下,可以通过ttl快速救砖. r4300主板有TTL的接线脚,脚的顺序可以找在OpenWrt的wiki上找到. 如下图4个TTL针在左下角,从下往上分别是GN ...

  5. Django的数据库读写分离

    Django的数据库读写分离 1.首先是配置数据库 在settings.py文件中增加多个数据库的配置: DATABASES = { 'default': { 'ENGINE': 'django.db ...

  6. U盘UEFI+GPT模式安装CentOS7.X系统

    1.制作CentOS7安装盘 还是老套路,开局先制作安装盘,UltraISO软碟通,上图   (1) 打开UltraISO软件,选择"文件"-> "打开" ...

  7. jackson学习之三:常用API操作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. CentOS 7.2系统安装步骤

    CentOS 7.2系统安装步骤 1.把系统U盘插到服务器上,然后启动服务器进入BIOS界面选择U盘启动. 根据服务器的不同,进入BIOS界面的按钮也不一样,主流的有F10.F11.F12.F2.ES ...

  9. 8.3 Customizing Git - Git Hooks 钩子 自动拉取 自动部署 提交工作流钩子,电子邮件工作流钩子和其他钩子

    https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks https://github.com/git/git/blob/master/temp ...

  10. 一个cgi的例子

    cgi的详细资料可以参考 http://httpd.apache.org/docs/2.4/howto/cgi.html 下面是一个python实现的cgi脚本,里面体现了一些cgi的用法,使用其他脚 ...