Manacher模板( 线性求最长回文子串 )
模板
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> using namespace std; ; ]; ], id, mx=; int L, R; //回文串在原串的左右端点位置 int Init() { int len = strlen(s); sNew[] = '$'; sNew[] = '#'; ; ; i < len; i++){ sNew[j++] = s[i]; sNew[j++] = '#'; } sNew[j] = '\0'; return j; } int Manacher() { int len = Init(); ; mx = ; ; i < len; i++){ * id - i], mx - i); ; ///在对象不是字符串时候,原本为了防止越界是左有'$' ///右有'\0',现在右边就没有'\0',需要人为填充替代! while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++; if (mx < i + p[i]){ id = i; mx = i + p[i]; } //max_len = max(max_len, p[i] - 1); //// 如果题目不要求输出回文串在原串的位置,则用下面代码更新答案 if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点 max_len = p[i]; L = (i - p[i])>>; R = (i + p[i] - )>>; ///R = (i + p[i])/2 -2; } } return max_len; /// 最后如若需要找到的回文串则是 /// for(int i=(id-mx+1);i<=(id+mx-1);i++) /// if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改 /// putchar(sNew[i]); }
p[i]-1 为以 i 为中心的回文长度
p[i]/2 表示回文半径
i%2==0 表示这个位置为字符,i/2-1 表示原字符串的位置
i%2==1 表示为字符中间,这两边的字符在原字符串的位置分别为 i/2-1 和 i/2
问题提出 : 给出一个串,要求在O(n)时间复杂度内计算出最长的回文子串
分析参考==> https://www.61mon.com/index.php/archives/181/ or https://www.felix021.com/blog/read.php?2040
相关题目 :
① HDU 3068
题意 : 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
分析 : 模板题
② POJ 3974
题意 : 给出一个串,求最长回文子串
分析 : 还是模板题
题意 : 中文题就不复述了
分析 : 实际上还是模板题,只要在回文判断两边相等的代码上加上递增这一条件即可
#include <iostream> #include <cstring> #include <algorithm> #include<stdio.h> using namespace std; ; const int INF = 0x3f3f3f3f; ]; ], id, mx=; int len; int Init() { s_new[] = -; s_new[] = INF; ; ; i < len; i++){ s_new[j++] = s[i]; s_new[j++] = INF; } return j; // 返回 s_new 的长度 } int Manacher() { int len = Init(); // 取得新字符串长度并完成向 s_new 的转换 ; // 最长回文长度 mx = ; ; i < len; i++){ * id - i], mx - i); // 需搞清楚上面那张图含义, mx 和 2*id-i 的含义 ; while (s_new[i - p[i]] == s_new[i + p[i]] && s_new[i - p[i]] <= s_new[i - p[i] + ]) p[i]++;// 不需边界判断,因为左有'$',右有'\0' if (mx < i + p[i]){ id = i; mx = i + p[i]; } max_len = max(max_len, p[i] - ); } return max_len; /// 最后如若需要找到的回文串则是 /// for(int i=(id-mx+1);i<=(id+mx-1);i++) /// if(s_new[i]!='#'&&s_new[i]!='$') /// putchar(s_new[i]); } int main(void) { int nCase; scanf("%d", &nCase); while(nCase--){ scanf("%d", &len); ; i<len; i++) scanf("%d", &s[i]); printf("%d\n", Manacher()); } ; }
④ HDU 3294
题意 : 首先给出一个字符,代表所有的字符真正对应的都往前移动,例如给出'b'那么真正的'a'就是'b','b'就是真正的'c',后来再给你一个串,问你通过上面转变后的最长回文子串是什么,给出首尾位置以及具体的回文序列
分析 : 这里多了一步需要具体定位回文,那么根据算法的具体意义,可以知道最长回文串的起始位置L=(i-p[i])/2,R=(i+p[i])/2-2,每一次更新答案都去更新L、R即可
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> using namespace std; ; ]; ], id, mx=; int L, R; //回文串在原串的左右端点位置 int Init() { int len = strlen(s); sNew[] = '$'; sNew[] = '#'; ; ; i < len; i++){ sNew[j++] = s[i]; sNew[j++] = '#'; } sNew[j] = '\0'; return j; } int Manacher() { int len = Init(); ; mx = ; ; i < len; i++){ * id - i], mx - i); ; ///在对象不是字符串时候,原本为了防止越界是左有'$' ///右有'\0',现在右边就没有'\0',需要人为填充替代! while (sNew[i - p[i]] == sNew[i + p[i]]) p[i]++; if (mx < i + p[i]){ id = i; mx = i + p[i]; } //max_len = max(max_len, p[i] - 1); //// 如果题目不要求输出回文串在原串的位置,则用下面代码更新答案 if(max_len < p[i]){ ///这里L、R记录的是最长回文子串在原串的左右端点 max_len = p[i]; L = (i - p[i])>>; R = (i + p[i] - )>>; ///R = (i + p[i])/2 -2; } } return max_len; /// 最后如若需要找到的回文串则是 /// for(int i=(id-mx+1);i<=(id+mx-1);i++) /// if(sNew[i]!='#'&&sNew[i]!='$') ///注意你设置的开头符号和填充符号,不同则需要修改 /// putchar(sNew[i]); } ]; int main(void) { char letter; while(~scanf(" %c", &letter)){ int num = letter - 'a'; ; i<; i++) mp[(i+num)%] = i; scanf("%s", s); int len = strlen(s); ; i<len; i++) s[i] = mp[s[i]-'a']+'a'; ){ printf("%d %d\n", L, R); for(int i=L; i<=R; i++) putchar(s[i]); puts(""); }else puts("No solution!"); } ; }
Manacher模板( 线性求最长回文子串 )的更多相关文章
- manacher算法_求最长回文子串长度
很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...
- Manacher算法 求 最长回文子串
1 概述(扯淡) 在了解Manacher算法之前,我们得先知道什么是回文串和子串. 回文串,就是正着看反着看都一样的字符串.比如说"abba"就是一个回文串,"abbc& ...
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...
- Manacher算法 O(n) 求最长回文子串
转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
随机推荐
- 【工具】Fiddler使用教程
目录 概述 2 Fiddler是做什么的,能帮助我们做什么? 2 工作原理 2 代理模式 3 使用场景--提供的功能 3 界面及使用介绍 3 常用功能 10 HOST配置 10 前后端接口连调--Co ...
- House_Of_Spirit ctf oreo程序分析
oreo程序下载 提取码:t4xx 程序分析 int __cdecl main() { leave_add = 0; leave_del = 0; leave_buf = (char *)&u ...
- java中线程同步的理解(非常通俗易懂)
转载至:https://blog.csdn.net/u012179540/article/details/40685207 Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运 ...
- Android - Unable to add window android.view.ViewRootImpl$W@6518342 -- permission denied for window type 2133
因为跟博主碰到了一样的问题,所以记录一下分析原理 原文链接:https://www.jianshu.com/p/b0364074288a 首先,先介绍下背景环境,第一,是Android7.0,其次,要 ...
- c++ k^1
如果k是偶数,则使k=k+1:若k是奇数,则使k=k-1.
- Tarjan水题系列(3):HNOI2006 潘多拉的魔盒
题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...
- js中的生成器函数
入门 简单来说,用法如下: function* fn() { console.log(1); //暂停! yield; //调用next方法继续执行 console.log(2); } var ite ...
- 远程连接mysql出现1130的错误
数据库权限不足 连接数据以后执行以下命令 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '您的数据库密码' WITH GRANT OP ...
- Verilog-2001标准在2001年就发布了
,不过翻了一些Verilog书籍,对Verilog-2001的新增特性很少有提及,即使提到了,也只是寥寥数语带过,其实在Verilog-2001中做了很多有用的改进,给编程带来很大的帮助,有必要详 ...
- linux c 的main 函数中的return 和 查看返回参数 argv 与 argc 作用
hello.c #include <stdio.h> int main(int argv, char* argc[]) { printf("hello word!\n" ...