文心大模型 LeetCode 5.最长回文子串 TypeScript实现
LeetCode 5. 最长回文子串 - TypeScript 实现
方法一:中心扩展法(推荐)
时间复杂度: O(n²) |空间复杂度: O(1)
【typescript】
function longestPalindrome(s: string): string {
if (s.length < 2) return s;
let start = 0;
let maxLen = 1;
// 中心扩展函数
const expandAroundCenter = (left: number, right: number): void => {
while (left >= 0 && right < s.length && s[left] === s[right]) {
const currentLen = right - left + 1;
if (currentLen > maxLen) {
maxLen = currentLen;
start = left;
}
left--;
right++;
}
};
for (let i = 0; i < s.length; i++) {
// 奇数长度回文(单字符中心)
expandAroundCenter(i, i);
// 偶数长度回文(双字符中心)
expandAroundCenter(i, i + 1);
}
return s.substring(start, start + maxLen);
}
方法二:动态规划
时间复杂度: O(n²) |空间复杂度: O(n²)
【typescript】
function longestPalindrome(s: string): string {
const n = s.length;
if (n < 2) return s;
// dp[i][j] 表示 s[i..j] 是否为回文
const dp: boolean[][] = Array.from({ length: n }, () => new Array(n).fill(false));
let start = 0;
let maxLen = 1;
// 单个字符都是回文
for (let i = 0; i < n; i++) {
dp[i][i] = true;
}
// 枚举子串长度
for (let len = 2; len <= n; len++) {
for (let i = 0; i <= n - len; i++) {
const j = i + len - 1;
if (s[i] === s[j]) {
if (len === 2) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
}
if (dp[i][j] && len > maxLen) {
maxLen = len;
start = i;
}
}
}
return s.substring(start, start + maxLen);
}
方法三:Manacher 算法(最优)
时间复杂度: O(n) |空间复杂度: O(n)
【typescript】
function longestPalindrome(s: string): string {
if (s.length < 2) return s;
// 预处理:插入特殊字符,统一奇偶情况
// 例: "aba" -> "^#a#b#a#$"
const t = '^#' + s.split('').join('#') + '#$';
const n = t.length;
const p: number[] = new Array(n).fill(0); // p[i] 表示以 t[i] 为中心的回文半径
let center = 0; // 当前回文中心
let right = 0; // 当前回文右边界
for (let i = 1; i < n - 1; i++) {
const mirror = 2 * center - i; // i 关于 center 的对称点
if (i < right) {
p[i] = Math.min(right - i, p[mirror]);
}
// 尝试扩展
while (t[i + p[i] + 1] === t[i - p[i] - 1]) {
p[i]++;
}
// 更新中心和右边界
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
}
// 找到最大半径及其位置
let maxLen = 0;
let centerIndex = 0;
for (let i = 1; i < n - 1; i++) {
if (p[i] > maxLen) {
maxLen = p[i];
centerIndex = i;
}
}
const start = Math.floor((centerIndex - maxLen) / 2);
return s.substring(start, start + maxLen);
}
测试用例
【typescript】
// 测试
console.log(longestPalindrome("babad")); // "bab" 或 "aba"
console.log(longestPalindrome("cbbd")); // "bb"
console.log(longestPalindrome("a")); // "a"
console.log(longestPalindrome("ac")); // "a" 或 "c"
console.log(longestPalindrome("racecar")); // "racecar"
算法对比
【表格】
方法 时间复杂度 空间复杂度 适用场景
中心扩展 O(n²) O(1) ✅ 面试推荐,简洁高效
动态规划 O(n²) O(n²) 需要子问题信息时
Manacher O(n) O(n) 追求极致性能
💡面试建议:优先掌握中心扩展法,思路清晰、代码简洁;如有余力再提 Manacher 算法作为优化方案。

更多推荐

所有评论(0)