原题如下:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
时间复杂度为n平方.总体思路如下:
首先,外层遍历从1开始寻找一个中心点,再一一比较中心点两边是否相等,比如说:
babad
一开始的中心点是a,下标i=1,我们比较一下s[i-1]和s[i+1]是否相等,如果相等,左边继续-,右边接着+,同时lenght同步计数.用maxlenght记录最大值.用max记录最大回文子串的起始位置.
同时考虑特殊情况,比如说:
baab 当i=1时,以a为中心,我们需要希望是s[i]和s[i+1]比较然后是s[i-1]和s[i+2]比较.这样子,当s[i]==s[i+1]时就有两种扩展方式,要两种都写出来.
代码如下:
var longestPalindrome = function(s) {
var l=s.length;
var lenght=1;
var max=0;
var maxlenght=0;
var flag=1;
var j,k;
var flag1=1;
if(s[0]==s[1]){
maxlenght=2;
max=0;
}
for(var i=1;i<l;i++){
flag=1;
flag1=1;
for(j=i,k=i;j>=1&&k<l-1&&flag;) {
if (s[i] == s[i + 1] && flag1 === 1) {
k++;
lenght++;
flag1 = 0;
if (lenght > maxlenght) {
maxlenght = lenght;
max = i;
}
}
j--;
k++;
//alert("i---"+i+"j---"+j+"k---"+k);
//alert(s[j]===s[k]);
if (s[j] == s[k]) {
lenght = lenght + 2;
}
else {
flag = 0;
if (lenght > maxlenght) {
maxlenght = lenght;
max = j + 1;
}
lenght = 1;
}
if ((j === 0 || k == l - 1) && s[j] === s[k]) {
if (lenght > maxlenght) {
maxlenght = lenght;
max = j;
}
lenght = 1;
}
}
// alert("长度是:"+lenght+"起点"+max);
// alert("i=="+i);
flag=1;
for(j=i,k=i;j>=1&&k<l-1&&flag;){
j--;
k++;
//alert("j=="+j+"k=="+k);
/*alert("i---"+i+"j---"+j+"k---"+k);
alert(s[j]===s[k]);*/
if(s[j]==s[k]){
lenght=lenght+2;
}
else{
flag=0;
if(lenght>maxlenght){
maxlenght=lenght;
max=j+1;
}
lenght=1;
}
if((j==0||k==l-1)&&s[j]==s[k]){
if(lenght>maxlenght){
maxlenght=lenght;
max=j;
}
lenght=1;
}
}
}
if(lenght>maxlenght){
maxlenght=lenght;
max=j;
}
if(l===1){
//alert("长度是1");
return s;
}
if(l===2&&s[0]===s[1]){
//alert("长度是2");
return s;
}else if(s[0]!==s[1]&&l===2){
//alert("长度是2");
return s[0];
}
var r=s.substr(max,maxlenght);
return r;
};
可是这样子好麻烦,能不能将s[i]==s[i+1]的时候扩展方式合并起来呢,答案当然是可以的,通过找资料发现,更简便的做法是:
当遇到相同的字符时,我们记录相同字符的起始位置和结束位置,以起始位置向左边扩展,以终点位置向右边扩展,举个例子:
sooos:
当i==1时,我们发现s[i]==s[i+],这时候我们记录下起点start是i,然后有3个o,所以相同字母字符串的终点end是3,这时候,咱们比较s[start-1]和终点s[end+];如果相同,就记录长度.这样就将两种扩展方式结合起来了.