码迷,mamicode.com
首页 > 其他好文 > 详细

hihoCoder#1032 最长回文子串

时间:2015-03-18 01:05:29      阅读:259      评论:0      收藏:0      [点我收藏+]

标签:

原题地址

 

这道题巧妙地利用了先前回文串的信息来减少后面的回文串计算量。

 

比如下面的字符串(圆圈代表字符)假设已经知道了某个字符的回文串情况(曲线连接的两个圆圈代表两个相同字符)

技术分享

 

思考:这能给后面的回文串计算带来什么帮助呢?

一个巴掌拍不响,看看已知两个回文串有什么效果:

技术分享

 

是不是有点意思了?为了更加直观,我们给曲线和点染色:

技术分享

 

还没明白在说什么?没关系,让我们把字母标上:

技术分享

技术分享

这下非常明显了吧,已知中心点在i和中心点在j的两个回文串,现在要求中心点在k的回文串,我们很容易就知道这个回文串的长度至少是5(3个蓝色点+2个橙色点)。

注意,这里求得的只是一个下界,目的是减少后续判定回文串的工作量。

令f[i]表示以i为中心点的回文串的长度,那么则有f[k] >= 5

 

原则上讲,k之前的所有已知回文串都可以用于计算这个下界,但毕竟我们就是计算一个下界,没必要非常精确。所以只是基于一个直观的想法去决定选择哪个点作为计算依据。即选择令 i + f[i] / 2 最大的那个i就行了。为什么是这个数呢?

假设有两个候选,i和i‘,他们对应的回文串情况如下图所示。

技术分享

那我们应该用i还是用i‘呢?我想,正常人应该都会选择用i而不是i‘吧。。

而上面那个式子(i + f[i] / 2)指的恰好就是回文串的右边界,也就是说,用这个i计算“应该”结果不赖。

 

好了,i确定了,j怎么办呢?因为我们知道一个巴掌拍不响啊。其实选择j非常简单,只需要把k沿着i对称一下就行了:

技术分享

技术分享

我们有f[k]‘ = f[j]。

记住,f[k]‘只是f[k]的一个下界,所以要想求得f[k]真正是多少,还是需要继续判断回文串,但是下界范围内的就不需要了,这就减少了判断回文串的工作量。

hihoCoder#1032 最长回文子串

标签:

原文地址:http://www.cnblogs.com/boring09/p/4346085.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!