题目来源:LeetCode5:最长回文子串
问题抽象:给定一个字符串 s,要求找出其最长的连续回文子串(即正读反读均相同的子串)。核心需求如下:
- 子串连续性:目标子串必须是原字符串中连续的字符序列(不可跳跃选择字符)。
- 回文性质:子串需严格满足
子串 = 子串的反转(如"aba"、"bb")。 - 长度最大化:当存在多个回文子串时,返回任意一个长度最长的子串本身(而非长度)。
- 中心扩展约束:需考虑以单字符或双字符为中心向两侧扩展的回文结构(如
"a"和"aa"均为有效回文)。 - 高效性要求:需避免 O(n³) 暴力解法,通常设计 O(n²) 或更优算法(如动态规划或中心扩散)。
输入:字符串 s(长度 ≥1)
输出:最长回文子串(字符串形式)
解题思路
题目要求找到字符串中最长的回文子串,核心思路是使用中心扩散法。回文串具有中心对称性,因此可以遍历字符串的每个字符以及每两个字符之间的位置作为中心点,向两边扩散,寻找以该中心为对称轴的最长回文子串。具体步骤如下:
- 初始化变量:记录最长回文子串的起始位置
start和结束位置end,以及当前最大长度maxLen。 - 遍历中心点:每个字符位置可作为奇数长度回文串的中心(如
aba),每两个字符之间可作为偶数长度回文串的中心(如abba)。 - 中心扩散:对于每个中心点,向左右两边扩散,直到字符不相等或到达边界,计算当前回文子串的长度。
- 更新最长回文子串:比较当前回文子串长度与已记录的最大长度,若更大则更新
start、end和maxLen。 - 返回结果:根据记录的起始和结束位置,返回最长回文子串。
此方法时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( 1 ) O(1) O(1),执行效率和内存消耗均较优。
代码实现(Java版)🔥点击下载源码
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
int maxLen = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i); // 奇数长度回文
int len2 = expandAroundCenter(s, i, i + 1); // 偶数长度回文
int len = Math.max(len1, len2);
if (len > maxLen) {
maxLen = len;
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1; // 返回回文子串长度
}
}
代码说明
-
核心方法
longestPalindrome:- 初始化变量
start和end用于记录最长回文子串的边界,maxLen记录当前最大长度。 - 遍历字符串的每个位置
i,分别作为奇数和偶数长度回文串的中心点。 - 调用
expandAroundCenter方法计算以当前中心扩散得到的回文子串长度。 - 比较并更新最长回文子串的边界和长度。
- 最终返回子串
s.substring(start, end + 1)。
- 初始化变量
-
辅助方法
expandAroundCenter:- 输入参数为字符串
s和左右指针left、right。 - 向左右两边扩散,直到字符不相等或越界。
- 返回回文子串的长度(计算方式为
right - left - 1,因为退出循环时左右指针指向不满足条件的边界)。
- 输入参数为字符串
提交详情(执行用时、内存消耗)


1209

被折叠的 条评论
为什么被折叠?



