5.最长回文子串--中等
题目说明
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例1
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例2
输入:s = "cbbd"
输出:"bb"
思路:
中心扩散法
大致做法就是遍历字符串,对于当前的字符,依次找其两侧的字符是否对称。
比如对于一个字符串“acbddbee”,若当前字符为第一个d(位置下标为3),用cur、left和right分别记录当前遍历的字符、当前字符的左边和右边位置,则:
- 先向右边一直寻找(left--)与当前字符(cur)相同的字符;
- 再向左边一直寻找(right++)与当前字符(cur)相同的字符;
- 最后左右一起同时扩散(left-- and right++),寻找左边和右边相等(left对应的字符 == right对应的字符)的字符。
为什么要分这三步进行?
我们可以分析一下回文串的情况,回文串可分为三种情况:
- 全部一模一样,如“cccccc”;
- 字符不尽相同但对称,又可细分为两种:“acdca”和“abba”;
- 以及二者的混合:如“abcccccba”;
对于1和3的情况,我们都需要中心扩散法的前两步找到回文串中完全相同的部分,然后再开始找不同但对称的部分
代码
#include <string>
using namespace std;
string func(string s){
int begin = 0;
int end = 0;
int right, left;
for(int i=0; i<s.size(); i++) {
left = i - 1;
right = i + 1;
while (left >= 0 && s[left] == s[i]) {
left--;
}
while (right < s.size() && s[right] == s[i]) {
right++;
}
while (left >= 0 && right < s.size() && s[left] == s[right]) {
left--;
right++;
}
if (end - begin < right - left) {
begin = left + 1;
end = right-1;
}
}
return s.substr(begin, end - begin + 1);
}