最长回文子串_POJ3974_O(n)完美求解--------入门级理解
2014-07-19 16:56
218 查看
首先你要知道什么是回文串?这个我不解释,然后是让我们求一个字符串的最长回文子串?、
对于如何求解最长回文子串,有几个层次首先当然是暴力求解
其次是找到一个回文串的中心点后向两端扩展,这么做可以求出来但是时间复杂性是O(n)
这一步有一个小亮点就是在对字符串的长度为奇数和偶数的时候采用了统一的处理即先对字符串进行预处理:
在每两个字符之间加入一个特殊字符把原始字符统一变为个数为奇数的新字符,
例如:
121 1#2#1
1221 1#2#2#1
最后一个完美的层次就是对上一步的改进:假设中心点为“i”,r(i)表示回文串的半径,[i-r(i),i]这些为中心点的回文子串的长度是已经求出来的,但是[i+1,i+r(i)]这些的回文子串是未知的,但是我们在求r(i)的时候已经搜索过了因此,就有了改进:(下面为转载)
manacher算法:
定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长
将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]?
由于s是从前扫到后的,所以需要计算p[i]时一定已经计算好了p[1]....p[i-1]
假设现在扫描到了i+k这个位置,现在需要计算p[i+k]
定义maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i]+i表示最大的
分两种情况:
1.i+k这个位置不在前面的任何回文串中,即i+k>maxlen,则初始化p[i+k]=1;//本身是回文串
然后p[i+k]左右延伸,即while(s[i+k+p[i+k]] == s[i+k-p[i+k]])++p[i+k]
2.i+k这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k
这样的话p[i+k]就不是从1开始
由于回文串的性质,可知i+k这个位置关于i与i-k对称,
所以p[i+k]分为以下3种情况得出
//黑色是i的回文串范围,蓝色是i-k的回文串范围,
![](http://img.blog.csdn.net/20140719164539702?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjMyOTkzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20140719164621573?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjMyOTkzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
对于如何求解最长回文子串,有几个层次首先当然是暴力求解
其次是找到一个回文串的中心点后向两端扩展,这么做可以求出来但是时间复杂性是O(n)
这一步有一个小亮点就是在对字符串的长度为奇数和偶数的时候采用了统一的处理即先对字符串进行预处理:
在每两个字符之间加入一个特殊字符把原始字符统一变为个数为奇数的新字符,
例如:
121 1#2#1
1221 1#2#2#1
最后一个完美的层次就是对上一步的改进:假设中心点为“i”,r(i)表示回文串的半径,[i-r(i),i]这些为中心点的回文子串的长度是已经求出来的,但是[i+1,i+r(i)]这些的回文子串是未知的,但是我们在求r(i)的时候已经搜索过了因此,就有了改进:(下面为转载)
manacher算法:
定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长
将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]?
由于s是从前扫到后的,所以需要计算p[i]时一定已经计算好了p[1]....p[i-1]
假设现在扫描到了i+k这个位置,现在需要计算p[i+k]
定义maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i]+i表示最大的
分两种情况:
1.i+k这个位置不在前面的任何回文串中,即i+k>maxlen,则初始化p[i+k]=1;//本身是回文串
然后p[i+k]左右延伸,即while(s[i+k+p[i+k]] == s[i+k-p[i+k]])++p[i+k]
2.i+k这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k
这样的话p[i+k]就不是从1开始
由于回文串的性质,可知i+k这个位置关于i与i-k对称,
所以p[i+k]分为以下3种情况得出
//黑色是i的回文串范围,蓝色是i-k的回文串范围,
相关文章推荐
- POJ3974 求字符串的最长回文子串的长度
- 最长回文子串 HDU3068 POJ3974 CF.7D
- Manacher算法: 最长回文子串O(N)时间内求解
- python实现对求解最长回文子串的动态规划算法
- 最长回文子串--轻松理解Manacher算法
- 求解最长回文子串 Manacher算法 之 POJ 3974
- 算法竞赛入门经典 3.3 最长回文子串
- HDU 4513 完美队列II(最长回文子串)
- 求解最长回文子串的长度
- Leetcode516.+Leetcode96. DP问题之求解最长回文子串+BST数目
- [算法] Manacher算法线性复杂度内求解最长回文子串
- Manacher 算法讲解 O(N)复杂度的 最长回文子串求解
- HiHo 1032 最长回文子串 (Manacher算法求解)
- Manacher算法求解最长回文子串
- 求解最长回文子串
- 求解最长回文子串的暴力求解
- 求解最长回文子串 之Manacher算法
- hihocoder _训练赛第一周_最长回文子串(不完美)
- 最长回文子串--轻松理解Manacher算法
- 最长回文子串--轻松理解Manacher算法