最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 最长回文子串的多种解法

    正文概述 掘金(Stoney_S)   2021-03-19   738

    1   题目及相关定义介绍

    1.1  题目介绍

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

    示例 1:
    
    输入:s = "babad"
    输出:"bab"
    解释:"aba" 同样是符合题意的答案。
    
    示例 2:
    
    输入:s = "cbbd"
    输出:"bb"
    
    提示:	1 <= s.length <= 1000	s 仅由数字和英文字母(大写和/或小写)组成
    

    题目来源:leetcode-cn.com/problems/lo…

    2.2 相关定义

    子串

    串中任意个连续的字符组成的子序列称为该串的子串;
    与之对应的还有一个概念,就是子序列,子序列就是在原来序列中找出一部分组成的序列;

    区别

    对于一个字符串而言:比如:helloStoney;
    子串是在字符串中,取出一块(连续的),如hello, Stoney;
    子序列指的是从字符串中,顺序取出字符,但是可以不连续,如:hlo, hlSn等

    2   暴力解法

    解法介绍

    最长回文子串的多种解法

    • 列举出所有的子串,时间复杂度:O(n^2)
    • 检查每一个子串是否为回文子串,每个子串的时间复杂度:O(n)
    • 总时间复杂度O(n^3), 空间复杂度O(1);

    3   动态规划解法

    3.1  解法详解

    动态规划解法是基于暴力解法的优化,优化的部分:判断每个串是否为回文串;
    时间复杂度:O(n^2);
    空间复杂度:O(n^2);
    空间复杂度可以优化至O(n);

    假设字符串("abbaba")为s,它的长度为n;
    定义dp数组,dp[i][j]:表示s[i][j]是否为回文子串,存储值为0, 1;
    分以下两种情况求出dp[i][j]的值:
    1,如果s[i, j]的长度(j - i + 1) <= 2时;

    • 如果s[i] === s[j],那么s[i][j]是回文串,所以dp[i][j] = s[i] === s[j];

    2,如果s[i, j]的长度(j - i + 1) > 2时;

    • 如果s[i + 1, j - 1]是回文串,并且s[i] === s[j],那么s[i, j]是回文串;
    • 所以dp[i][j] = dp[i + 1, j - 1] && s[i] === s[j];

    3.2   代码实现

    var longestPalindrome = function(s) {
        let length = s.length;
        if(s == null) return null;
        if(length <= 1) {
            return s;
        }
        let dp = Array.from(new Array(length), () => new Array(length).fill(0));
        let maxlen = 1;
        let begin = 0;
        for (let i = length - 1; i >= 0; i--) {
            for (let j = i; j < length; j++) {
                let len = j - i + 1;
                dp[i][j] = (s[i] === s[j]) && (len <= 2 || dp[i + 1][j - 1]);
                if(dp[i][j] && len > maxlen) {
                    maxlen = len;
                    begin = i;
                }
            }
        }
        return s.substring(begin, begin + maxlen)
    };
    

    4   扩散中新解法

    4.1  解法介绍

    最长回文子串的多种解法

    如果所示:有两种扩散方式;
    假设字符串("abbaba")的长度为n,那么一共有n + (n - 1) = 2n - 1个扩展中心;
    时间复杂度:O(n^2)
    空间复杂度:O(1);

    4.2  代码实现

    var longestPalindrome = function(s) {
        if (s === null) return null;
        let length = s.length;
        if(length <= 1) return s;
        let maxLen = 1;
        let begin = 0;
        for (let i = length  - 2; i >= 1; i--) {
            // 以字符中心向左右扩散
            let len1 = palindromeLength(s, i - 1, i + 1);
            // 以字符右边的间隙为中心向左右扩散
            let len2 = palindromeLength(s, i, i + 1);
            len1 = Math.max(len1, len2);
            if(len1 > maxLen) {
                maxLen = len1;
                begin = i - ((maxLen - 1) >> 1);
            }
        }
        // 以0号字符右边的间隙为中心的最长回文子串长度是2
        if(s[0] === s[1] && maxLen < 2) {
            begin = 0;
            maxLen = 2;
        }
        return s.substring(begin, maxLen + begin)
    };
    
    // 从l开始向左扩散,从r开始向右扩散,获得最长回文子串的长度
    function palindromeLength(s, l, r) {
        while(l >= 0 && r < s.length && s[l] === s[r]) {
            l--;
            r++;
        }
        return r - l - 1;
    }
    

    5   扩散中心解法优化

    5.1  解法介绍

    最长回文子串的多种解法

    算法的核心思想:由连续的相同的字符组成的子串作为扩散中心;
    所以,"babbbabaa"的扩散中心有:"b",  "a",  "bbb",  "a",  "b",  "aa";

    核心思想
    找到左边第一个不等于s[i]的字符,记为位置r,  i左边位置记为l;
    r作为下一次的i;
    由l开始向左,r开始向右扩展,找到最长的回文子串;

    5.2   代码实现

    var longestPalindrome = function(s) {
        if (s === null) return null;
        let length = s.length;
        if(length <= 1) return s;
        let maxLen = 1;
        let begin = 0;
        let i = 0;
        while(i < length) {
            let l = i - 1;
            // 找到右边第一个不等于s[i]的位置
            let r =  i;
            while(++r < length && s[r] === s[i]);
            // r会成为新的i
            i = r; 
            // 从l向左,r向右扩散
            while(l >= 0 && r < length && s[l] === s[r]) {
                l--;
                r++;
            }
            // 扩展结束后,cs[l + 1, r)就是刚才找到的最大回文子串
            // ++l后, l就是刚才找到的最大回文子串的开始索引
            let len = r - ++l;
            if(len > maxLen) {
                maxLen = len;
                begin = l;
            }
        }
        return s.substring(begin, begin + maxLen)
    };
    

    起源地下载网 » 最长回文子串的多种解法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元