93.最长回文子串

2 阅读1分钟

题目链接

给你一个字符串 s,找到 s 中最长的 回文 子串。

解法1 暴力解法

思路

判断回文串用双指针即可,把它抽出来作为一个函数。然后两层循环即可、为什么要两层循环?是为了避免漏掉从 i 开始到中间某个索引是回文串。

暴力解法可以ac。

代码

function longestPalindrome(s: string): string {
    let result = "";
    for (let i = 0; i < s.length; i++) {
        for (let j = i + 1; j <= s.length; j++) {
            const temp = s.substring(i, j); // s[i..j-1]
            if (temp.length < result.length) {
                continue;
            }
            if (temp.length > result.length && isPalindrome(temp)) {
                result = temp;
            }
        }
    }
    return result;
};

function isPalindrome(s: string): boolean {
    // 判断是否是回文
    let i = 0;
    let j = s.length - 1;
    while (i < j) {
        if (s[i] !== s[j]) {
            return false;
        }
        i++;
        j--;
    }
    return true;
}

时空复杂度

时间复杂度:O(n^3),两层循环为 O(n^2),判断回文串 isPalindromeO(n)

空间复杂度:O(n)

解法2 中心扩展算法

思路

因为回文串具有对称性,所以如果找到一个中点,向两边扩展最有效率。

而回文也可以分成两种情况:奇数长度回文 aba 和偶数长度回文 abba

所以在遍历时也要分两种情况:以 i 为中心(单字符);以 ii+1 为中心(双字符)。

然后再判断其长度更新答案即可。

代码

function longestPalindrome(s: string): string {
    if (s.length < 2) return s;

    let result = "";
    for (let i = 0; i < s.length; i++) {
        const odd = expandAroundCenter(s, i, i);
        const even = expandAroundCenter(s, i, i + 1);

        const longer = odd.length > even.length ? odd : even;
        if (longer.length > result.length) {
            result = longer;
        }
    }

    return result;
};

function expandAroundCenter(s: string, left: number, right: number): string {
    // 向两边扩展寻找回文
    while (left >= 0 && right < s.length && s[left] === s[right]) {
        left--;
        right++;
    }
    return s.substring(left + 1, right);
}

时空复杂度

时间复杂度:O(n^2)

空间复杂度:O(1)