最长回文子串js

题目描述

  • 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:
输入: “cbbd”
输出: “bb”

解答

暴力破解

外面的两层循环找到所有子串,第三层循环判断子串是否是回文。方法的时间复杂度为O(n^3),空间复杂度为O(1)。

var longestPalindrome = function(s) {
    let n = s.length;
    let result = ''
    for(let i = 0;i<n;i++){
        for(let j=i+1;j<=n;j++){
            let str = s.slice(i,j);
            let f = str.split('').reverse().join('');
            
            if(str == f){
                result = str.length > result.length ? str : result;
            }
        }
    }
    console.log(result);
    
    return result;
};

动态规划

最长回文子串js_第1张图片

var longestPalindrome = function(s) {
    let len = s.length;
    let result;
    let i,j,L;
    let dp=Array(len).fill(0).map(x=>Array(len).fill(0));
    //console.log(dp);
    if(len<=1){
        return s
    }
    // 只有一个字符的情况是回文
    for(i = 0;i<len;i++){
        dp[i][i] = 1
        result = s[i]
    }

    // L是i和j之间的间隔数(因为间隔数从小到大渐增,所以大的间隔数总能包含小的间隔数)
    // i     j
    // abcdcba.length = L   所以 L = j-i+1; => j = i+L-1;
    for ( L = 2; L <= len; L++) {
        // 从0开始
        for ( i = 0; i <= len - L; i++) {
                j = i + L - 1;
            if(L == 2 && s[i] == s[j]) {
                dp[i][j] = 1;
                result = s.slice(i, i + L);
            }else if(s[i] == s[j] && dp[i + 1][j - 1] == 1) {
                dp[i][j] = 1
                result = s.slice(i, i + L);
            }

        }
    }
    //console.log(result);
    return result;
}

最长回文子串js_第2张图片

Manacher算法

首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#。

然后用一个数组 P[i] 来记录以字符S[i]为中心的最长回文子串向左/右扩张的长度(包括S[i],也就是把该回文串“对折”以后的长度),比如S和P的对应关系:

S # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1

添加链接描述

你可能感兴趣的:(JS)