此题和 力扣 的第五题一样, 力扣 要求输出回文子串,oj只要求输出长度,但思路相同。
大体思路为:从中心向两边进行扩展寻找,双指针,若两个字符相同,则左右指针分别向左向右移动一个单位,最终返回最大回文串的长度。这个函数的难点在于,回文串的字符个数有可能是奇数有可能是偶数,因此对于每一个字符,要进行两次左右扩展的寻找。一次是以他本身为中心,一次是以他和他右面的元素一起为中心进行寻找。之后比较出二者中较大的那个。若mlen比当前数组长度打,则进行更新,对数组的起始位置进行移动。end = i + mlen / 2; 之后由end - start + 1 = mlen可推出start的表达式,再对start进行平移。
#include <iostream>
#include <string>
using namespace std;
int zuichangduichenzichuan(int len, string s);
int zhongxinchangdu(string s, int left, int right);
int main(){
int len;
cin >> len;
string s;
cin >> s;
cout << zuichangduichenzichuan(len, s);
return 0;
}
int zuichangduichenzichuan(int len, string s) {
if(len==0 || len==1) return len;//若字符串长度为0或1,则其本身就是最大回文子串
int start = 0;//记录回文子串起始位置
int end = 0;//记录回文子串终止位置
int mlen = 0;//记录最大回文子串长度
for(int i = 0; i < len; i++){
int len1 = zhongxinchangdu(s, i, i);//以s[i]为中心,找寻奇数长度的回文串
int len2 = zhongxinchangdu(s, i, i+1);//以s[i]和s[i+1]为中心,找寻偶数长度的回文串
mlen = max(mlen, max(len1, len2));
if(mlen > end - start + 1){
end = i + mlen / 2;
start = end - mlen + 1;//因为end-start+1=mlen
}
}
return mlen;
}
int zhongxinchangdu(string s, int left, int right){
//计算以left和right为中心的回文串长度
int l = left;
int r = right;
while(l>=0 && r < s.length() && s[l]==s[r]){
l--;
r++;
}
return r - l + 1 - 2;
}
力扣的和oj的题目差不多,只不过力扣要求输出这个字符串,s.substr(start, mlen)即为输出