给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
算法思路分析:回文子串有两种一种的单点对称中心,形如“aba”,而另外一种就是双点对称中心,形如“abba”。所以只要在原字符串中寻找出最长的字串即可。由于涉及到对称中心点的问题,所以自然而然的想到利用for循环遍历字符串,以及双指针围绕对称中心进行前后移动。
string longestPalindrome(string str) {
int length = str.size();
int max = 0;//最大的的长度
int maxBegin = 0;//最大长度的起始位置
for (int i = 0; i < length; ++i) {
//从下标开始遍历每一个以当前字符为中心的最长字符
int tempMax = 1;//中间暂时最长回文子串的长度
int strTempBegin = i - 1;//待加入最长子串的前字符
int strTempEnd = i + 1;//待加入最长子串的后字符
while (strTempBegin >= 0 && strTempEnd < length &&
str[strTempBegin] == str[strTempEnd]) {
//如果待加入子串的前后字符下标合法,且两端的字符相等
--strTempBegin;//前指针前移
++strTempEnd;//后指针后移
tempMax += 2;//回文子串的长度自增2
}
if (tempMax > max) {
//更新最长回文子串的长度,和其对应的起始下标
max = tempMax;
maxBegin = strTempBegin + 1;
}
if (i < length - 1 && str[i] == str[i + 1]) {
//如果当前中心字符与其后一个字符相等,那么就寻找以i和i-1为双中心的最长子串
tempMax = 2;//因为是双中心,所以初始化长度为2
strTempBegin = i - 1;//待加入最长子串的前字符
strTempEnd = i + 2;//待加入最长子串的后字符
while (strTempBegin >= 0 && strTempEnd < length &&
str[strTempBegin] == str[strTempEnd]) {
//如果待加入子串的前后字符下标合法,且两端的字符相等
--strTempBegin;//前指针前移
++strTempEnd;//后指针后移
tempMax += 2;//回文子串的长度自增2
}
if (tempMax > max) {
//更新最长回文子串的长度,和其对应的起始下标
max = tempMax;
maxBegin = strTempBegin + 1;
}
}
}
//在原子串中切出最长回文子串
string longestSubStr = string(str, maxBegin, max);
return longestSubStr;
}
以下是算法思路的示意图: