5. Longest Palindromic Substring
Medium
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd"
Output: "bb"
试题链接:https://leetcode.com/problems/longest-palindromic-substring/
法一:动态规划 O(n^2)
维护二维数组dp,dp[i][j]表示字符串区间[i, j]是否为回文串。
当i = j时,只有一个字符,肯定是回文串。
当i = j + 1,说明是相邻字符,判断s[i]是否等于s[j]。
当i - j >= 2,即i和j不相邻时,2个条件即为回文:1)s[i]和s[j]相等,2)dp[j + 1][i - 1]若为真。
综上写出递推式如下:
dp[i, j] = 1 if i == j
= s[i] == s[j] if j = i + 1
= s[i] == s[j] && dp[i + 1][j - 1] if j > i + 1
法二:对称中心向两边扩散
2.1.暴力法 O(n^2)
注意:奇数长度子串和偶数长度字串的对称中心不同,便利时二者都要讨论。
2.2.马拉车法 O(n)
第一步:改造原字符串,将奇数和偶数统一成奇数问题。
原始:1 2 2 1 2 2 // 记为str
改造:# 1 # 2 # 2 # 1 # 2 # 2 #
第二步:改造串前加上一个字符,为了方便计算最后结果的下标。
改造:$ # 1 # 2 # 2 # 1 # 2 # 2 # // 记为数组t
第三步:维护数组p,p[i]记录以t[i]为中心的最长回文半径。
t:$ # 1 # 2 # 2 # 1 # 2 # 2 #
p:- 1 2 1 2 5 2 1 6 1 2 3 2 1
找规律,发现:
str回文长度 = t回文半径 - 1
str回文起始位置 = (t回文中心位置 - t回文半径) / 2
第四步:重点在于p数组如何求
从左往右计算数组P[ ], Mi为当前取得最大回文串的中心位置,而R是最大回文串能到达的最右端的值。
1)当 i <=R时,找到点 i 关于 Mi 的对称点 j ,其值为 j= 2*Mi-i 。因点 j 、i 在以Mi 为中心的最大回文串的范围内([L ,R]),
a)那么如果P[j] <R-i (同样是L和j 之间的距离),说明,以点 j 为中心的回文串没有超出范围[L ,R],由回文串的特性可知,从左右两端向Mi遍历,两端对应的字符都是相等的。所以P[ j ]=P[ i ],如下图:
b)如果P[ j ]>=R-i (即 j 为中心的回文串的最左端超过 L),如下图所示。即,以点 j为中心的最大回文串的范围已经超出了范围[L ,R] ,这种情况,以点 j 为中心的回文串的最左端超过L,那么在[ L, j ]之间的字符肯定能在( j, Mi ]找到相等的,由回文串的特性可知,P[ i ] 至少等于R- i,至于是否大于R-i(图中红色的部分),我们还要从R+1开始一一的匹配,直达失配为止,从而更新R和对应的Mi以及P[ i ]。
2)当 i > R时,如下图。这种情况,没法利用到回文串的特性,只能老老实实的一步步去匹配。
代码:
class Solution {
public:
string longestPalindrome(string s) {
string t = "$#";
for(int i = 0; i < s.size(); ++i){
t += s[i];
t += "#";
}
t += "#";
int p[2002];
int mi = 1, r = 1, resmi = 1, reslen = 1;
p[1] = 1;
for(int i = 2; i < s.size() * 2 + 2; ++i){
p[i] = (i < r)? min(p[mi * 2 - i], r - i): 1;
while (t[i + p[i]] == t[i - p[i]]) ++p[i];
if (i + p[i] > r){
mi = i;
r = i + p[i];
}
if (reslen < p[i]){
resmi = i;
reslen = p[i];
}
}
return s.substr((resmi - reslen) / 2, reslen-1);
}
};
马拉车方法参考链接:https://www.cnblogs.com/love-yh/p/7072161.html
http://www.cnblogs.com/grandyang/p/4475985.html