实用算法实现-第 8 篇 后缀树和后缀数组 [4 最长回文子串]
2011-10-16 13:31
330 查看
8.5 最长回文子串
定义字符串S的逆序为S’,有S’[i]=S[n - i - 1](0 ≤ i < len(S),下文所有i处于这个区间内)。其中len(S)为S的长度。如果S和S’相同,则称S为回文串(Palindrome)。S的最长回文子串就是S的所有子串中是回文串且长度最长的字符串。定义Suffix(S, i)为S以S[i]开头且包含S[i]的后缀字符串。
定义Prefix(S, i)为S以S[i]结尾且包含S[i]的后缀字符串。
令n = Len(S)
可知有如下性质:
1. Len(S’) = Len(S) = n;
2. Len(Suffix(S, i)) = Len(S) - i;
3. Len(Prefix(S, i)) = i;
4. Prefix(S, i) = Suffix’(S’, len(S) - i- 1);
5. Suffix(S, i) = Prefix’(S’, len(S) - i- 1);
6. (S’)’ = S.
要求S的最长回文子串,可以对i在区间[0, len(S))内枚举,找出以S[i]为中心字符的最长回文子串。所有这些回文子串中最长的那个就是S的最长回文子串。
求以S[i]为中心字符的最长回文子串的问题可以描述为:
求一对下标(j, k),满足下列条件:
1. 0 ≤ j ≤ i, i ≤ k < len(S)。因为j,k是S的下标,且一个比i小,一个比i大。
2. i - j = k - i = x。因为所求字符串以S[i]为中心字符。
3. Suffix’(Prefix(S, i), j) = Prefix(Suffix(S,i), k - i) = T。因为所求字符串为回文字符串。
4. x最大
可知在满足条件1的情况下,有:
Suffix’(Prefix(S, i), j)
= Prefix’’(Prefix’(S, i), Len(Prefix(S,i)) - j - 1) 性质5
= Prefix’’(Prefix’(S, i), i + 1 - j - 1) 性质3
= Prefix(Prefix’(S, i), i - j) 性质6
= Prefix(Suffix’’(S’, Len(S) - i - 1), i- j) 性质4
= Prefix(Suffix(S’, Len(S) - i - 1), i -j) 性质6
= Prefix(Suffix(S’, Len(S’) - i - 1), i -j) 性质1
= Prefix(Suffix(S’, n - i - 1), i - j)
所以第三个条件转化为:
Prefix(Suffix(S’, n - i - 1), i - j) = Prefix(Suffix(S,i), k - i)
又由于有条件2,进一步写为:
Prefix(Suffix(S’, n - i - 1), x) =Prefix(Suffix(S, i), x) = T
观察该条件,可知T是Suffix(S, i)和Suffix(S’, n - i - 1)的公共前缀。进一步地,要满足条件4,使x最大,就是使得公共前缀T最长。该最大公共前缀就是所求的以S[i]为中心字符的最长回文子串。
而求一个串的两个后缀的最长公共前缀正是后缀数组所擅长的事情,后缀数组可以在线性的预处理时间后支持O(1)的LCP询问。
所以求以S[i]为中心字符的最长回文子串的方法即为:构建字符串W = S?S',其中?是S的字符表中不存在的字符。在W中,S[i]对应W[i],S'[n - i - 1]对应W[n + 1 + n - i - 1] = W[2n - i]。故此SA[rank(i)]和SA[rank(2n - i)]的最长公共前缀就是最长回文子串,LCP(rank(i), rank(2n- i))就是最长回文子串的长度max(x)。
8.6 实例
8.6.1 最长公共子串
PKUJudgeOnline, 3450, Corporate Identity.PKUJudgeOnline, 3080, Blue Jeans.
8.6.2 两个串的最长公共子串
PKUJudgeOnline, 2774, Long Long Message.本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsdev/article
相关文章推荐
- 实用算法实现-第 8 篇 后缀树和后缀数组 [4 最长回文子串]
- 实用算法实现-第 8 篇 后缀树和后缀数组 [2 最长公共子串]
- 实用算法实现-第 8 篇 后缀树和后缀数组 [2 最长公共子串]
- 实用算法实现-第 8 篇 后缀树和后缀数组 [3 两个字符串的最长公共子串]
- 实用算法实现-第 8 篇 后缀树和后缀数组 [3 两个字符串的最长公共子串]
- 实用算法实现-第8篇 后缀树和后缀数组 [1简介]
- 实用算法实现-第8篇 后缀树和后缀数组 [1简介]
- java 实现后缀数组及最长回文子串问题
- URAL 1297 后缀数组:求最长回文子串
- 【后缀数组|最长回文子串】URAL-1297 Palindrome
- ural 1297 Palindrome求最长连续回文子串(后缀数组求法)
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
- ural 1297 后缀数组 最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)
- 【后缀数组】【最长回文子串】Palindrome Ural_1297
- URAL 1297 最长回文子串(后缀数组)
- 【LeetCode-面试算法经典-Java实现】【005-Longest Palindromic Substring(最长回文子串)】
- 最长回文子串—Manacher 算法 及 python实现