题目描述
给定一个字符串 s,找到 s 中最长的回文子串。
解题思路
暴力解法
枚举所有可能的子串,然后检查每个子串是否是回文。这种方法的时间复杂度是 O(n^3),其中 n 是字符串的长度。
动态规划
使用一个二维数组 dp[i][j] 来表示子串 s[i…j] 是否是回文。状态转移方程是 dp[i][j] = (s[i] == s[j]) && (j - i < 2 || dp[i+1][j-1])。这种方法的时间复杂度是 O(n^2)。
中心扩展法
遍历字符串中的每个字符或每对相邻字符(一个中心可能是单个字符,也可能是两个相邻字符),尝试将中心向两边扩展,检查扩展后的子串是否是回文。
这种方法的时间复杂度也是 O(n^2),但由于它避免了额外的空间开销(除了几个变量外),因此在实际应用中往往表现良好。
代码示例(中心扩展法-Javascript)
var longestPalindrome = function(s) {
if (s.length < 2) return s;
let start = 0, maxLength = 1;
// 辅助函数,用于检查以 left 和 right 为中心的回文子串的最大长度
const expandAroundCenter = (left, right) => {
while (left >= 0 && right < s.length && s[left] === s[right]) {
if (right - left + 1 > maxLength) {
start = left;
maxLength = right - left + 1;
}
left--;
right++;
}
};
// 遍历每个字符和每对相邻字符作为中心
for (let i = 0; i < s.length - 1; i++) {
expandAroundCenter(i, i); // 奇数长度的回文子串
expandAroundCenter(i, i + 1); // 偶数长度的回文子串
}
return s.substr(start, maxLength);
};