题目
求一个字符串的最大回文前缀长度。回文是指正反方向读起来都一样的字符串,比如“abcdcba”就是一个回文。
那么abccba的长度为6。列子2:10010的回文长度为4。列子3:sogou的回文长度是1,因为就一个a。
解析
这个题目是求回文前缀的长度,因为是前缀所以意思就是从第一个字符开始如果有回文的话,这个回文长度为多少。那么有俩种算法都是O(n2),第一种从头遍历,第二种从尾遍历。N的平方是根据,这样来的,对于第一种情况字符串全是同一个字符的话,那么每次都要求回文所以是N的平方。对于第二种abaaaaa,这种情况也是每次都要求回文也是N的平方,虽然回文是1。
差别在于第二种最优为O(N)
我是这样想的,先遍历字符串,如果遇见与第一个字符相等的字符的话,我们先看下这个字符是否是回文,如果是回文返回长度。不是继续遍历。
第一种遍历的话,如果第一个子串是回文,那么我们如果在后面在遇到了与第一个字符相等的字符的话,还是要看下新的子串是否是回文。
第二种遍历的话,如果第一个子串是回文直接结束,如果不是的话继续从上一次的end位置往后面遍历。
代码
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int Fun(char*start, char*end)
{
int ret = end - start + 1;
while (start<end)
{
if (*start == *end)
{
start++;
end--;
}
else{
return 1;
}
}
return ret;
}
int main()
{
string s;
cin >> s;
int start = 0;
int ret = 1;
int size = s.size();
int end = size - 1;
while (start<end)
{
if (s[end] == s[0])
{
ret = std::max(ret, Fun(&s[start], &s[end]));
}
if (ret>1) break;
end--;
}
cout << ret << endl;
return 0;
}