给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路
动态规划: 主要是要状态转移方程
P(i,j)=(P(i+1,j−1)&&S[i]==S[j]),其中由于p(i,j)之前要知道p(i+1,j-1),因此遍历时采用由后往前遍历。
回文子串长度为1和2时,单独考虑。
string longestPalindrome(string s) {
int len = s.size();
vector<vector<int>> dp(len, vector<int>(len));
string res = "";
//p(i,j) = (p(i+1,j-1) && s[i] == s[j])
for(int i = len-1; i >=0; i--)
{
for(int j = i; j < len; j++)
{
dp[i][j] = (s[i] == s[j]) && (j - i < 2 || dp[i+1][j-1]);
//比较长度
if(dp[i][j] && j-i+1 > res.size())
{
res = s.substr(i, j-i+1);
}
}
}
return res;
}
其它方法
中心扩展
因为回文字符串是中心对称的。因此以各中心向两边扩展比较是否相等,判断是否是回文。包含奇数和偶数一共有n+n-1个中心;
Manacher’s Algorithm 马拉车算法
其思想也是利用了中心扩展法,不过在它的基础上充分利用了回文特点。先将原字符串进行变换,如下
原字符串: abc
改变后: #a#b#c#
其次重点理解maxRight,center这两个变量。
maxRight 是指已出现的回文字符串最右边字符的索引。center是对于的回文中心。这两者是一一对应的。
在遍历过程中,当遍历到 i 时,需要判断 i 和 maxRight的大小。
i >= maxRight 这时,只需按照中心扩展法即可
i < maxRight 因为回文对称的特点,找到 i 对关于center对称的点 mirror , p[mirror]为扩展步数。如果 p[mirror]+i < maxRight ,p[i] = p[mirror] (注:i 和 mirror 是镜像对称的,在没超出center 为 中心的回文字符串时,因此 mirror 点是回文长度等于 i 点)。否则p[i] 暂时等于maxRight-i。后面继续中心扩展计算。
string longestPalindrome(string s) {
//变换字符串,插入'#'
int len = s.size();
string news = "#";
for(int i = 0; i < len; ++i)
{
news += s[i];
news += '#';
}
int slen = 2* len +1; //变化后字符串的长度
int maxRight= 0; //回文右边扩展最大的索引
int center = 0; //回文中心
int start = 0; //原字符串回文起始位置
int maxLen = 1; //回文字符串的长度
int* p = new int[slen];
for(int i = 0; i < slen; i++)
{
p[i] = 0;
}
for(int i = 0; i < slen; ++i)
{
if(i < maxRight)
{
//找到i 关于center 对称的点
int mirror = 2 * center -i;
p[i] = min(maxRight-i, p[mirror]); //需要理解
}
int left = i - (1+p[i]);
int right = i + (1 + p[i]);
while(left >= 0 && right < slen && news[left] == news[right] ) //注意边界
{
p[i]++;
left--;
right++;
}
//判断maxRight是否更新
if(i+p[i] > maxRight)
{
maxRight = i+p[i];
center = i;
}
//比较回文长度
if(p[i] > maxLen)
{
maxLen = p[i];
start = (i-maxLen)/2;
}
}
return s.substr(start, maxLen);
}

本文探讨了在给定字符串中查找最长回文子串的算法,包括动态规划、中心扩展及马拉车算法(Manacher’s Algorithm)。动态规划通过状态转移方程实现,中心扩展利用回文对称性,马拉车算法则结合了两者的优势。
907

被折叠的 条评论
为什么被折叠?



