Longest Palindromic Substring
来源:互联网 发布:萤火视频桌面软件 编辑:程序博客网 时间:2024/06/05 15:19
题目:
Given a string S, find the longest palindromic substring in S.即
给出一个字符串S,找到一个最长的连续回文串。
例如串 babcbabcbaccba 最长回文是:abcbabcba
分析:
首先将输入字符串S, 转换成一个特殊字符串T,转换的原则就是将S的开头结尾以及每两个相邻的字符之间加入一个特殊的字符,例如#
例如: S = “abaaba”, T = “#a#b#a#a#b#a#”.
为了找到最长的回文字串,例如我们当前考虑以Ti为回文串中间的元素,如果要找到最长回文字串,我们要从当前的Ti扩展使得 Ti-d … Ti+d 组成最长回文字串. 这里 d 其实和 以Ti为中心的回文串长度是一样的. 进一步解释就是说,因为我们这里插入了 # 符号,对于一个长度为偶数的回文串,他应该是以#做为中心的,然后向两边扩,对于长度是奇数的回文串,它应该是以一个普通字符作为中心的。通过使用#,我们将无论是奇数还是偶数的回文串,都变成了一个以Ti为中心,d为半径两个方向扩展的问题。并且d就是回文串的长度。
例如 #a#b#a#, P = 0103010, 对于b而言P的值是3,是最左边的#,也是延伸的最左边。这个值和当前的回文串是一致的。
如果我们求出所有的P值,那么显然我们要的回文串,就是以最大P值为中心的回文串。
T = # a # b # a # a # b # a #P = 0 1 0 3 0 1 6 1 0 3 0 1 0
例如上面的例子,最长回文是 “abaaba”, P6 = 6.
根据观察发现,如果我们在一个位置例如 abaaba的中间位置,用一个竖线分开,两侧的P值是对称的。当然这个性质不是在任何时候都会成立,接下来就是分析如何利用这个性质,使得我们可以少算很多P的值。
下面的例子 S = “babcbabcbaccba” 存在更多的折叠回文字串。
Now we are at index i = 15, and its mirrored index around C is i’ = 7. Is P[ 15 ] = P[ 7 ] = 7?
当时当i = 15的时候,却只能得到回文 “a#b#c#b#a”, 长度是5, 而对称 i ' = 7 的长度是7.
如上图所示,如果以 i, i' 为中心,画出对称的区域如图,其中以i‘ = 7 对称的区域是 实心绿色 + 虚绿色 和 左侧,虚绿色表示当前的对称长度已经超过之前的对称中心C。而之前的P对称性质成立的原因是 i 右侧剩余的长度 R - i 正好比 以 i‘ 为中心的回文小。
then P[ i ] ← P[ i' ]
else P[ i ] ≥R – i. (这里下一步操作是扩充 P[ i ].
扩充P[i] 之后,我们还要做一件事情是更新 R 和 C, 如果当前对称中心的最右延伸大于R,我们就更新C和R。在迭代的过程中,我们试探i的时候,如果P[i'] <= R - i, 那么只要做一件事情。 如果不成立我们对当前P[i] 做扩展,因为最大长度是n,扩展最多就做n次,所以最多做2*n。 所以最后算法复杂度是 O(n)
代码如下:
string preprocess(string s)
{
string t;
int n=s.length();
for(int i=0;i<n;i++)
{
t+="#";
t+=s[i];
}
t+="#";
return t;
}
int min(int a,int b)
{
return a<b?a:b;
}
string longestPalindrome(string s) {
int n=s.length();
if(n<=1)return s;
string t=preprocess(s);
n=n*2+1;
int *array=new int[n];
for(int i=0;i<n;i++)
{
array[i]=0;
}
array[1]=1;
array[n-2]=1;
int c=1,r=2;
for(int i=2;i<n-2;i++)
{
int sym=2*c-i;
if(r>i)
{
array[i]=min(r-i,array[sym]);
}
while((i-array[i]-1)>=0&&(t[i-array[i]-1]==t[i+array[i]+1]))array[i]++;
if(i+array[i]>r)
{
r=i+array[i];
c=i;
}
}
int maxlen=0;
int j=0;
for(int i=0;i<n;i++)
{
if(array[i]>maxlen)
{
maxlen=array[i];
j=i;
}
}
return s.substr((j-maxlen)/2,maxlen);
}
- LeetCode: Longest Palindromic Substring
- LeetCode Longest Palindromic Substring
- LeetCode: Longest Palindromic Substring
- [Leetcode] Longest Palindromic Substring
- Longest Palindromic substring
- [LeetCode] Longest Palindromic Substring
- LeetCode5:Longest Palindromic Substring
- Leetcode : Longest Palindromic Substring
- Longest Palindromic Substring
- Longest Palindromic Substring
- [LeetCode]Longest Palindromic Substring
- leetcode Longest Palindromic Substring
- Longest Palindromic Substring
- LeetCode-Longest Palindromic Substring
- Longest Palindromic Substring
- Longest Palindromic Substring
- [LeetCode] Longest Palindromic Substring
- Longest Palindromic Substring leetcode
- cocos2d-x 自适应
- Thinkphp学习笔记(三)输入方式和连接数据库的方式
- poj 2762 Going from u to v or from v to u?
- struts2 运行错误
- __super in MFC
- Longest Palindromic Substring
- DM6467开发领航-开发坏境安装
- iframe 在IE下透明背景
- Thinkphp学习笔记(四)CURD
- web.xml 中的listener、 filter、servlet 加载顺序及其详解
- URAL 1297 Palindrome(SA 求最长回文子串)
- linux下可执行文件的库们
- 导出文件在IE和火狐中文件名乱码问题的解决
- java获取url网页指定内容