目录
一、前言
二、题目描述
三、预备知识
🥝 什么回文串 ?
四、题目解析
五、总结与提炼
六、共勉
一、前言
最长回文子串 这道题,可以说是--回文专题 --,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中,面试官可能会从多个方面考察这道题目,所以大家需要对这道题目非常熟悉哦!!
本片博客就来详细的讲讲解一下 最长回文子串 的实现方法,让我们的面试变的更加顺利!!!
二、题目描述
题目链接:5. 最长回文子串 - 力扣(LeetCode)
三、预备知识
🥝 什么回文串 ?
回文串 的概念就是正着读和倒着读是一样的字符串,分为以下两种情况
① 11211 ---- 奇数个
② 112211
---- 偶数个
不难发现,除了中间的字符外,所有的字符均在一首一尾出现了一次,也就是说,出现在两边的字符数量一定是偶数,只有出现在中间的字符数量可以是奇数
- 现在,我们把上述①、②回文串拆分成
left,
mid,
right
三个部分,如下图
- 「回文串」长度为偶数:所有不同字符的出现次数都为「偶数」;
- 「回文串」长度为奇数:位于中点的字符出现「奇数」次,其余字符出现「偶数」次;
因此,某字符串是回文串排列之一的「充要条件」为:此字符串中,最多只有一种字符的出现次数为「奇数」,其余所有字符的出现次数都为「偶数」。
四、题目解析
中心扩展法
- 如果中心点相等(s[i] = s[j]),就检查各自的下一位是否相等 s[i-1] = s[j+1]?。
- 我们可以把每个字符 s[i] 作为子串的中心,然后依次往两边进行搜索。要注意的是,每个字符可以构成奇数长度和偶数长度。因此我们中心要分两种情况进行枚举。
- 中心扩散的方式最后我们得到的是子串的中心索引和长度,为了截取子串,我们需要推算子串起点索引。
class Solution {
public:
string longestPalindrome(string s)
{
//中心扩展算法
int begin = 0 , len = 0 , n = s.size();
for(int i = 0; i < n;i++) // 依次枚举所有的中点
{
//先做一次奇数次的扩展
int left = i , right = i;
//确保 left 和 right 不能越界
while(left >=0 && right < n && s[left]==s[right])
{
left--;
right++;
}
// 如果新的长度大于之前的长度,那就更新
if(right-left-1 > len)
{
// 计算其实位置和长度
begin = left + 1; // 因为每次循环 left 和 right 会多运行一次
len = right - left -1;
}
//再做一次偶数次的扩展
left = i , right = i + 1;
while(left >=0 && right < n && s[left]==s[right])
{
left--;
right++;
}
if(right-left-1 > len)
{
begin = left + 1;
len = right - left -1;
}
}
return s.substr(begin,len);
}
};
五、总结与提炼
最后我们来总结一下本文所介绍的内容,本文讲解来一道力扣中有关 最长回文子串 的题目,这道题目是校招笔试面试中有关 回文 章节非常高频的一道题目,大家下去一定要自己再画画图,分析一下,把这段代码逻辑自己实现一遍,才能更好地掌握 !!
六、共勉
以下就是我对 最长回文子串 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 回文专题 的理解,请持续关注我哦!!!