问题介绍
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
解题思路
之前一直害怕回文串的问题,是因为一直没有正视这个问题,也可能是被网上各种神级解法搞害怕了,看完别人的解答后总是忍不住发出一声“牛x”,但是后面就没有认真思考了。这里记录一下比较直接暴力的方法,不知道算不算动态规划呢?反正我不太会写状态转换方程。
首先我们要知道回文串的特点,从左读和从右读是一样的结果,这种思路很容易就让人无从入手,因为你不知道左右点到底在哪里。所以我们需要转换一个思路,我们先确定中间的点,这样子就比较容易写代码了,因为确定中间的点,就可以用两层循环解决这个问题。首先最外层循环就是遍历中间的点的位置,有n个数;确定中间点位置后,就进行两端扩展,直接left-1和right+1不相等,就得到该位置的最长回文串长度。但是还得判断的是,如果中间位置是两个数的情况,因此多加一个判断即可,看看两个数的回文串长度比较长还是一个数的回文串长度比较长。代码如下:
class Solution {
public:
string longestPalindrome(string s) {
int res_l = 0, res_r = 0;
int max_n = 1;
for(int i=0; i<s.size()-1; i++){
int left=i, right=i;
while(left>0 && right<s.size()-1){
if(s[left-1] != s[right+1]){
break;
}else{
left--; right++;
}
}
if(max_n < right-left+1){
max_n = right - left + 1;
res_l = left; res_r = right;
}
if(s[i] == s[i+1]){
left = i; right = i+1;
while(left>0 && right<s.size()-1){
if(s[left-1] != s[right+1]){
break;
}else{
left--; right++;
}
}
if(max_n < right-left+1){
max_n = right - left + 1;
res_l = left; res_r = right;
}
}
}
return s.substr(res_l, max_n);
}
};