题目描述(c++):
给定一个字符串 c++s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"。
思路:
1.考虑:回文字符串的最大特点即其对称性,再考虑两种情况:奇数长度和偶数长度的对称轴是不同的,可能需要进行分开讨论。
2.考虑:要从哪里开始遍历,是否需要递归,是否需要多个遍历,或者是从两边往里面遍历,只用一次遍历是否可行?
3.思索:根据其对称性,倘若给我一个回文字符数组,我可以确定从中间值开始(倘若这个是奇数数组),那么往两边走,它的值ch[middle+i]和ch[middle-i]一定有:
//奇数长度的数组
ch[middle+i]==ch[middle-i] 为true
//其中i={0,1,2,3...}
//偶数长度的数组
ch[middle+i]==ch[middle-i+1] 为true
//其中i={1,2,3...}
基于这个思路,我先遍历一遍整个字符数组,获取到所有的满足:
条件1:“左一字符”==“右一字符”
或者
条件2: “本字符”==“右一字符”
将满足条件1的放进一个vector的容器1,满足条件2的放在一个vector的容器2。
然后遍历这两个容器,以容器1为例子,将每个容器的下标的值,然后在原始字符串s里往左右方向展开搜索,当遇到
“左一字符”==“右一字符”
临时记录数++;
当遇到
“左一字符”!=“右一字符”
退出循环,比较最大回文字符串数,假如更新了最大值,就把当前的容器下标值进行更新与记录。
最后,判断最大字符串数maxCount的情况:
maxCount%2==0 还是 maxCount%2!=0
因为你已经知道对称中心的下标位置,以及整个字符串的长度,很容易就能够获得结果。最后附上源码:
class Solution {
public:
string longestPalindrome(string s) {
const char *oriChar=s.data();
int length=s.size();
int maxStartIndex=-1;
int maxCount=0;
for(int i=0;i<length-1;i++){
if(oriChar[i]==oriChar[i+1]){
int count=0;
for(int j=0;j<=i;j++){
if(i+j+1>=length||i-j<0) break;
if(oriChar[i-j]==oriChar[i+1+j]){
count++;
}else{
break;
}
}
if(count*2>=maxCount){
maxStartIndex=i;
maxCount=2*count;
}
}
if(i>0){
if(oriChar[i-1]==oriChar[i+1]){
int count=0;
for(int j=1;j<=i;j++){
if(i+j>=length||i-j<0) break;
if(oriChar[i-j]==oriChar[i+j]) count++;
else break;
}
if(count*2+1>=maxCount){
maxStartIndex=i;
maxCount=2*count+1;
}
}
}
}
if(maxCount==0)return string(oriChar,1);
if(maxCount%2==0){
char * result=new char[maxCount];
char * oriRes=s.data();
result=oriRes+maxStartIndex-(maxCount/2-1);
return string(result,maxCount);
}else{
char * result=new char[maxCount];
char * oriRes=s.data();
result=oriRes+maxStartIndex-(maxCount-1)/2;
return string(result,maxCount);
}
}
};
在源码里,我做了优化,就省略了容器的使用,判断到有符合条件的下标,就直接进行回文字符串的长度检查~
最后为Leetocde的用时: