【leetcode】5.最长回文子串js

题目

代码-中心扩散法

好这题还是看题解了。

思路是采用中心扩散法,遍历到一个字符就以它为中心向两边扩散看最长的回文子串长度多少,如果比现有的长就更新当前最长的回文子串,没有就继续往下遍历。需要注意的点是回文子串可能是奇数长度和偶数长度两种情况。

javascript 复制代码
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function(s) {
    if (s.length < 2) return s
    let res = ''
    for (let i = 0; i < s.length; i++) {
        // 回文字串长度是奇数
        helper(i, i)
        // 回文字串长度是偶数
        helper(i, i+1)
    }
    function helper(left, right) {
        while (left >= 0 && right < s.length && s[left] === s[right]) {
            left--
            right++
        }
        // 这里用right - left - 1是因为循环之后left和right恰好是不满足条件的时刻
        // 因此两个边界不能取,应该取left + 1到right - 1这个区间
        if (right - left - 1 > res.length) {
            // slice左闭右开,取[left + 1, right - 1]
            res = s.slice(left + 1, right)
        }
    }
    return res
};

时间复杂度是O(n²),空间复杂度是O(1)

代码-动态规划

原题解在这里:传送门(特别厉害啊我膜拜)

1. 定义dp数组

用一个二维数组dpij来表示字符串中下标从i到j的子串si...j是不是回文子串

2. 状态转移规则

  • 当 si !== sj,显然 si..j 不是回文串;
  • 当 si === sj 时:
    • 若 j - i < 3(子串长度为2或3),只要两端字符相等就是回文串;
    • 否则要看内部子串 dpi + 1j - 1 是否为回文。

3. 状态初始化

所有dpii都是true,因为只有单个字符肯定是回文。

4. 最终目标

在遍历过程中记录最长回文的起始下标 begin 和长度 maxLen,最终用 s.substring(begin, begin + maxLen) 返回。

这里就直接贴佬的代码了可供学习参考。

javascript 复制代码
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function(s) {
    const len = s.length;
    if (len < 2) return s; // 长度小于2,直接返回原串

    let maxLen = 1; // 初始化最大长度
    let begin = 0;  // 初始化起始位置
    const dp = Array.from({ length: len }, () => Array(len).fill(false));

    // 所有长度为1的子串都是回文串
    for (let i = 0; i < len; i++) {
        dp[i][i] = true;
    }

    const charArray = s.split('');

    // 枚举子串结束位置 j
    for (let j = 1; j < len; j++) {
        // 枚举子串起始位置 i(必须 i < j)
        for (let i = 0; i < j; i++) {
            if (charArray[i] !== charArray[j]) {
                dp[i][j] = false;
            } else {
                if (j - i < 3) {
                    dp[i][j] = true; // 长度为2或3,只要两端相等就是回文
                } else {
                    dp[i][j] = dp[i + 1][j - 1]; // 否则依赖内部是否回文
                }
            }

            // 更新最长回文子串的位置和长度
            if (dp[i][j] && j - i + 1 > maxLen) {
                maxLen = j - i + 1;
                begin = i;
            }
        }
    }

    return s.substring(begin, begin + maxLen);
};

时间复杂度和空间复杂度都是O(n²)

相关推荐
Navigator_Z1 天前
LeetCode //C - 1187. Make Array Strictly Increasing
c语言·算法·leetcode
龍德明宇1 天前
如何理解大语言模型的负主体性-龍德明宇
人工智能·算法·大语言模型llm·负主体性·ai存在论
白狐_7981 天前
408数据结构第6章:迪杰斯特拉(Dijkstra)算法——真题精讲
数据结构·算法
皓月斯语1 天前
P2858 [USACO06FEB] Treats for the Cows G/S
数据结构·c++·算法·动态规划
旖旎夜光1 天前
LeetCode 397:整数替换(贪心问题) —— 题解
数据结构·c++·算法·leetcode·贪心算法
奈斯先生Vector1 天前
2026 开发者效能革命:基于创源AIGC 与开源生态的工程化实践、安全沙箱与代码智能体协同
人工智能·算法·架构·prompt·aigc
依然鸣1 天前
PTA团体程序设计天梯赛L2真题讲解L2-037-040
c++·经验分享·学习·算法·蓝桥杯·深度优先·pat考试
Sagittarius_A*1 天前
哈希与认证基础(一):哈希函数的安全目标:原像、第二原像与碰撞
算法·安全·信息安全·密码学·哈希算法
坚持编程的菜鸟1 天前
模拟实现strncat
c语言·算法·模拟实现strncat
wabs6661 天前
关于哈希表【力扣1.两数之和的思考】
数据结构·算法·leetcode·散列表·图论