描述
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例一:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例2:
输入:s = "cbbd"
输出:"bb"
思路
这题最好想到的思路就是找到一个数然后从两端开始找,即中心扩散法
- 边界情况,首先长度是1时,直接返回,2的是否,如果两个字符相等,直接返回,否则返回任意一个
- 长度大于2时,任意取一个非边界字符,然后判断该字符两端是否相等,不相等则结束这个字符的回文判断
- 如果相等则继续取两端,知道不相等为止
- 由边界情况知,也可能起点位置的字符其相邻位置可能存在任意连续的相同字符,因此首先把该字符相邻的所有相同字符取出来,然后再开始从两端按照步骤2处理
算法如下
var longestPalindrome = function(s) {
if (s.length === 1) {
return s;
} else if (s.length === 2) {
if (s[0] === s[1]) {
return s
}
return s[0]
} else {
let start = 1, left, right, i = 1;
let end = s.length - 1;
let result = ''
// 选中某一位作为起点,向两端扩散
for (start = 1; start < end; start++) {
left = start;
right = start;
i = 1;
// 首先找到左右相邻的连续相同字符
while(left > 0 && s[start] === s[left - 1]) left--;
while(right < end && s[start] === s[right + 1]) right++;
// 边界条件,到达两端就是边界
result = result.length < right - left + 1 ? s.substring(left, right + 1) : result;
//console.log('初始值', result, start, left, right)
while(left - i >= 0 && right + i <= end) {
// 不符合回文数,退出本次查找,起始点前进
if (s[left - i] !== s[right + i]) {
break;
} else if (result.length < 2 * i + right - left + 1) {
// 当前回本长度大于结果集,存储最新的
result = s.substring(left - i, right + i + 1)
//console.log('找到的', result)
}
i++;
}
//console.log('result', result)
}
return result;
}
};
ps:leetcode刷题随笔,欢迎交流