推荐使用中心扩展法——时间复杂度o(n²)、空间o(1),因暴力法o(n³)易卡顿,动态规划虽o(n²)但需o(n²)空间;其核心是遍历2n−1个中心(单字符或双字符间),双向扩展并实时更新最长回文起始位与长度。

PHP 中求最长回文子串,推荐使用中心扩展法——时间复杂度 O(n²),空间 O(1),代码简洁、易懂、高效,适合大多数实际场景。
为什么不用暴力或动态规划?
暴力解法(枚举所有子串再判断回文)时间复杂度达 O(n³),n > 1000 时明显卡顿;动态规划虽优化到 O(n²) 时间 + O(n²) 空间,但需额外二维数组,内存开销大且初始化繁琐。中心扩展法在保持 O(n²) 时间的同时,仅用常数空间,且逻辑更贴近直觉。
中心扩展法核心思路
回文串对称,其“中心”可能是某个字符(奇数长,如 "aba"),也可能是两个字符之间(偶数长,如 "abba")。遍历每个可能的中心(共 2n−1 个),向两边同步扩展,记录最长有效回文的起始位置和长度。
- 对每个下标 i,分别以 i 为中心(奇数长度)和以 i 与 i+1 之间为中心(偶数长度)扩展
- 扩展时检查左右字符是否相等,一旦不等立即停止
- 实时更新最长长度和对应起始索引
PHP 实现代码(带注释)
php
function longestPalindrome($s) {
if (empty($s)) return '';
$n = strlen($s);
$start = $maxLen = 0;
// 遍历每个中心位置(0 到 n-1 为单字符中心,0 到 n-2 为双字符间隙中心)
for ($i = 0; $i
// 奇数长度:以 $i 为中心
$len1 = expandAroundCenter($s, $i, $i);
// 偶数长度:以 $i 和 $i+1 之间为中心
$len2 = expandAroundCenter($s, $i, $i + 1);
$len = max($len1, $len2);
if ($len > $maxLen) {
$maxLen = $len;
$start = $i - intval(($len - 1) / 2); // 推算起始下标
}
}
return substr($s, $start, $maxLen);
}
function expandAroundCenter($s, $left, $right) {
$n = strlen($s);
while ($left >= 0 && $right
$left--;
$right++;
}
// 回文长度 = 扩展后右 - 左 - 1
return $right - $left - 1;
}
// 示例调用
echo longestPalindrome("babad"); // 输出 "bab" 或 "aba"
echo longestPalindrome("cbbd"); // 输出 "bb"
?>
边界与注意事项
字符串为空或单字符时需直接返回;PHP 中字符串支持下标访问($s[$i]),无需转数组;注意起始索引计算:奇数长时中心在 i,半径为 (len−1)/2;偶数长时中心在 i 和 i+1 之间,起始为 i − len/2 + 1,统一公式为 $i − intval(($len − 1) / 2) 可兼容两种情况。
立即学习“PHP免费学习笔记(深入)”;











