这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
前言
最长回文子串是非常经典的一道算法习题,难度还是有的,做之前一定充分考虑各种情况,要不然就会不断踩坑,特别是字符串有中心点和没中心点的情况,以及字符串长度小于2的情况,废话不多说直接开干。
题目描述
给你一个字符串s,找到s中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba"同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
示例 3:
输入:s = "a"
输出:"a"
示例 4:
输入:s = "ac"
输出:"a"
解题思路
- 最长回文子串,看到这个题目的时候我的第一想法又是转换成数组,但明显是想多了,自己太菜了,字符串直接就可以通过下边进行获取各项的,所以转数组直接pass掉
- 首先拿到输入的字符串,要考虑的第一个情况就是长度小于2的情况,这种情况下直接返回s即可
- 重点来了,最长回文分为两种情况,一种是有中心点的情况,一种是没有中心点的情况,也就是如下例子,s='abad'(这是有中心点的情况,中心点就是b),s='abbad'(这就是没有中心的情况,也可以说中心点是bb两个字符),由于我们无法知道字符串中是情况一还是情况二,因此我们需要同时对每一项进行两种操作,也就是当第一种情况时(中心点是i,那就要比较i-1和i+1的情况),当是第二种情况的时候(中心点可以当做是i,但比较的是i和i+1),第二种情况比较难理解,需要好好理解一下
- 通过对每个字符进行上述两种情况的操作就会得到结果,代码如下
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
if(s.length<2){ //s长度小于2,也就是长度为1,直接返回
return s
}
let start = 0 //记录最长回文子串起点
let maxLength = 1 //记录最大长度
function expandAroundCenter(left,right){
while(left>=0 && right<=s.length && s[left]===s[right]){ //要同时满足这三个情况才可以进行下一步操作
if(right-left+1>maxLength){ //right-left + 1 也就是目前回文串的长度
maxLength = right -left +1
start =left
}
left--
right++
}
}
for(let i=0;i<s.length;i++){
expandAroundCenter(i-1,i+1)
expandAroundCenter(i,i+1)
}
return s.substring(start,start+maxLength)
};
总结
最长回文子串这个算法还是有一定难度的,比较难理解的就是有中心点和无中心点的两种情况,一定要加以区分,对每一个字符进行两种情况的运算,即可得到结果。
大家如有高见,欢迎赐教。