- 解题思路
中心扩展法:所谓中心扩展法,就是从一个中心往两边扩展判断
step1:给定字符串s,下标i,根据中心扩展法,我们需要往两边扩展判断
left = i - 1;right = i + 1
如果s[left]等于s[right]则继续往两边扩展判断
当s[left]不等于s[right]时结束,这时候返回right-left就是回文串的长度
function search(s,l,r){
var left = l;
var right = r;
while(left >= 0 && right < s.length && s[left] === s[right]){
left--;
right++;
}
return right - left - 1; //right - left - 2 + 1 减二是因为上一个判断循环了一次left-- 和 right++
}
step2:由于字符串aba和abba都是回文字符串,所以这两种类型全都要判定,我们给left,right的赋值就会不同,给定字符串s,下标i,第一种回文字符串aba使left=right=i,第二种abba使left=i,right=i+1,所以每个下标要使用两次中心扩展法。
for(var i = 0 ; i < s.length; i++){
var len1 = search(s,i,i)
var len2 = search(s,i,i+1)
}
step3:通过上面的代码,我们已经找出了回文串的长度,那么接下来就是怎么得到它了。我们要得出所有回文子串中最长的那一个,为了后面方便得到回文子串,定义最长回文子串的开始下标start和结束下标end,最长回文子串就是s.slice(start,end+1)。
var start = end = 0
for(var i = 0 ; i < s.length; i++){
var len1 = search(s,i,i)
var len2 = search(s,i,i+1)
var len = Math.max(len1,len2)
if(len > end -start){
start = i - Math.floor((len - 1) / 2)
end = i + Math.floor(len / 2)
}
}
return s.slice(start,end+1)
step4:这里有必要说start = i - Math.floor((len - 1) / 2);end = i + Math.floor(len / 2)是怎么得到的
假设坐标为i,当length为奇数时,i为中心点,取子字符串
起始坐标 i_start = i - (len-1)/2
终止坐标 i_end = i + (len-1)/2
假设坐标为i,当length为偶数时,i为中心前置点,取子字符串
起始坐标 i_start = i - (len)/2 - 1
终止坐标 i_end = i + (len)/2
那么整理一下就是
i_start = i - (len-1)/2 ------------ length为奇数
i_start = i - (len)/2 - 1 ------------ length为偶数
换算一下就是
i_start = i - (len-1)/2 == i - Math.floor((len-1)/2) ------------ length为奇数
i_start = i - (len)/2 - 1 == i - (len-2)/2 == i - Math.floor((len-1)/2) ------------ length为偶数
同理
i_end = i + (len-1)/2 == i + Math.floor(len / 2) ------------ length为奇数
i_end = i + (len)/2 == i + Math.floor(len / 2) ------------ length为偶数
所以给定i对于所有length的回文子串响应的起始和终止坐标
start = i - Math.floor((len - 1) / 2)
end = i + Math.floor(len / 2)
- 代码
var longestPalindrome = function(s) {
var start = end = 0
for(var i = 0 ; i < s.length; i++){
var len1 = search(s,i,i)
var len2 = search(s,i,i+1)
var len = Math.max(len1,len2)
if(len > end -start){
start = i - Math.floor((len - 1) / 2)
end = i + Math.floor(len / 2)
}
}
return s.slice(start,end+1)
function search(s,l,r){
var left = l,
right = r;
while(left >= 0 && right < s.length && s[left] === s[right]){
left--;
right++;
}
return right - left - 1;
}
};