Problem
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
Solving
中心移位法
以0.5作为一个步长,让中心点center进行滑动,考虑到数据类型的统一,我们使用2倍的中心点center来作为变量,所以步长0.5只需要对center自增1。初始中心为0,回文字符串长度为0。寻找以索引0为中心的最长回文字符串,并更新最长回文字符串的长度和回文字符串本身;接着以(center+1)为中心,通过扩展回文字符串的方式,直接进行比较,举个例子,当前的最长回文字符串长度为3,而移位后的center中心为5.5,那我们直接判断4和7是不是相同,如果不相同,则表明当前中心的最长回文字符串长度必然小于4,因为索引4567构成的字符串不是回文字符串,那这个中心点对最长回文字符串是没有贡献的,中心点再次移位;另外一种情况就是相同了,那我们直接判断索引4和索引7之间的字符串是否回文即可,如果回文,则更新最长回文字符串和长度,并以当前中心点为中心,继续扩大长度,寻找最长回文字符串,找到后中心移位。无论哪一种操作,最后中心都会移位。如此循环下去!
Code(c++)
class Solution {
public:
string longestPalindrome(string s) {
int center=0;
int length = 0;
int max_index, min_index;
string res;
while(center+length<s.length()*2){
int flag = 1;
if ((center+length)%2){
max_index = (center+length+1)/2;
min_index = (center-length-1)/2;
}
else{
max_index = (center+length)/2;
min_index = (center-length)/2;
}
for(int i=min_index; i<=center/2; ++i){
if(s[i] != s[center-i]){
flag = 0;
break;
}
}
while(flag){
length = max_index-min_index+1; // 更新回文字符串长度
res = s.substr(min_index, length); // 更新最长回文字符串
--min_index;
++max_index;
if (min_index>=0 && max_index<s.length()){
if (s[min_index] != s[max_index])
flag = 0;
}
else
flag = 0;
}
++center; // 更新回文字符串中心
}
return res;
}
};
执行用时 :16 ms
内存消耗 :16 MB
注意:
代码中的第一层循环也可以写成for循环的形式,将++center直接合并到步长中去