最长回文子串-manacher算法
来源:互联网 发布:网络诈骗有哪些 编辑:程序博客网 时间:2024/06/10 02:14
像kmp一样,先来看一道题目
给出一个长度为n的字符串S,
求S的子串T,令T反转后T`与T完全相等,求T最大的长度。
首先,可以想到用暴力做,枚举所有的子串,然后判断,时间复杂度为
第二,可以发现,如果子串S[1..5]是一个回文串,那么S[2..4]自然也是一个回文串。
利用这个性质,可以枚举所有串的回文中心,然后从中间向两边去查找、判断。
最后的时间复杂度为
显然,这仍然不够优,kmp能够实现线性时间完成,那么这个问题也能用线性的时间完成吗?
答案是肯定了,这就需要manacher这个算法来实现。
首先,可以充分利用刚才发现的规律,就可以通过左半部分的对称中心的答案得到右半边的对称中心的答案
如果是一个回文串S
那么,可以得到一个数组
分别是
这个F就是十六进制下的15
可以发现,F所在的位置就是S串的中心,
首先,以此可以发现
然后根据
再根据上一句,可以得到
那么
最后比较发现
所以
所以manacher算法的原理就是从左到右求各个中心的答案,然后根据最长的回文串再来根据左边的回文中心的答案推出右边的答案。
如果需要
用这种方法可以避免重复比较,也充分地利用了前面的信息
但是现在仍然有一个问题,如果长度是偶数的怎么解决。
答案是在字符串前加上一个未出现过的字符,然后在原有的字符之间再插入这个字符,最后再加上一个,但是防止越界,于是在开头再放一个另一种字符,在结尾也放一个没有出现过的字符。
这样做,就可以把所有偶数的情况都转化为奇数。
以下为代码:
int manacher() { int mx = 0, ans = 0, po = 0; for(int i = 1; i <= lenT; i++) { if(mx > i) { Len[i] = min(mx - i, Len[2 * po - 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; po = i; } ans = max(ans, Len[i]); } return ans - 1;}
那么,最后再来看一下时间复杂度,不难猜到,这也是利用线性时间就能解决问题的算法,这个算法在运行时,while每运行一次,p至少向右移一下,所以while最多执行N次,其他的跟着for循环最多执行N次,所以最终总时间为
- Manacher算法求最长回文子串
- Manacher算法求最长回文子串
- 最长回文子串(Manacher算法)
- Manacher算法 最长回文子串
- 最长回文子串的manacher算法
- 最长回文子串,Manacher算法
- Poj3974 最长回文子串 Manacher算法
- 最长回文子串 manacher算法
- Manacher算法(最长子回文串)
- hihocoder1032(最长回文子串manacher算法)
- HDU3068(最长回文子串manacher算法)
- 最长回文子串 用manacher算法
- hiho1032 : 最长回文子串 Manacher算法
- 最长回文子串 - Manacher算法
- 最长回文子串Manacher算法
- Manacher算法 - 最长回文子串
- manacher算法-最长子回文串
- 最长回文子串-Manacher算法
- Java 必备技能——基本工具篇
- CSS——NO.4(继承、层叠、特殊性、重要性)
- 文章标题
- Android RGB颜色查询对照表
- Httpwatch中http状态码列表
- 最长回文子串-manacher算法
- 【Leetcode】Insert Delete GetRandom O(1)
- 安装部署(二) Ubuntu 安装配置 MySQL Connector Java
- 一名出色程序员的必备技巧----与程序员兄弟们共享
- LinQ数据查询,联合查询 委托扩展
- 系统硬盘分区模式之GPT
- 人人都在谈的平台创业,一文教你看懂平台商业模式
- 《Android开发艺术探索》之学习笔记(一)Activity的生命周期和启动模式
- java基础学习(8)4种引用类型简析StrongReference、 SoftReference、 WeakReference 、PhantomReference