跳到主要内容

LeetCode 5. 最长回文子串

本节目标

枚举奇偶中心并向两侧扩展,得到最长连续回文子串。

题意与约束

返回字符串中的最长连续回文子串;长度为一的字符本身就是回文。

第一反应与重复子问题

区间 DP 可由更短内部区间判断,但本题还可比较中心扩展:每个回文都有一个奇或偶中心。

状态定义与转移推导

固定中心后向两侧扩展,s[left] == s[right] 才能继续;每次成功扩展就比较当前长度与最优答案。

正确性依据

任意回文子串都有唯一的中心类型,枚举全部中心并扩展到不能扩展时,必会检查到全局最长回文。

样例执行过程

abcbad 以中间 c 为中心依次得到 cbcbabcba,继续扩展时两端越界,因此记录长度五。

代码实现

C++17
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

class Solution {
public:
string longestPalindrome(string s) {
int n = static_cast<int>(s.size());
int bestLeft = 0;
int bestLength = 0;
for (int center = 0; center < n; center++) {
for (int left = center, right = center; left >= 0 && right < n && s[left] == s[right]; left--, right++) {
if (right - left + 1 > bestLength) {
bestLeft = left;
bestLength = right - left + 1;
}
}
for (int left = center, right = center + 1; left >= 0 && right < n && s[left] == s[right]; left--, right++) {
if (right - left + 1 > bestLength) {
bestLeft = left;
bestLength = right - left + 1;
}
}
}
return s.substr(bestLeft, bestLength);
}
};

复杂度分析

共有 O(n) 个奇偶中心,每次扩展最多 O(n),时间 O(n²),额外空间 O(1)

边界与易错点

空串返回空串;偶数长度回文必须以相邻双中心开始,不能只枚举单个字符中心。

模式迁移

需要“是否为回文”的许多区间查询时改用区间 DP;只求单个最长子串时中心扩展更直接。回到区间动态规划