node.js - JavaScript 算法题求解——最长的回文子字符串?
PHP中文网
PHP中文网 2017-04-10 15:10:34
[JavaScript讨论组]

https://leetcode.com/problems/longest-palindromic-substring/

Given a string S, find the longest palindromic substring in S. You may
assume that the maximum length of S is 1000, and there exists one
unique longest palindromic substring.

输入字符串 S, 求字符串中最长的回文子字符串,并返回,如输入 dbakokabbbbbbb 返回 bakokab

var longestPalindrdome = function (s) {
    var t = s.split("").join("#");
    var c = 1, e = 0, cs = 0;
    t = "~" + t + "#";

    for (var j = 1, lenj = t.length - 1; j < lenj; j++, c = 1) {
        while (t[j + c] === t[j - c]){
            c++;
        }

        if (c > e) {
            e = c;
            cs = j;
        }

    }

    var result = t.slice(cs - e + 1, cs + e).replace(/#/g, "").replace(/~/g, "");
    return result;
};

求解更快的算法,不知道 200ms 的算法是怎么样的?

测试用例之一:

var s = 'whdqcudjpisufnrtsyupwtnnbsvfptrcgvobbjglmpynebblpigaflpbezjvjgbmofejyjssdhbgghgrhzuplbeptpaecfdanhlylgusptlgobkqnulxvnwuzwauewcplnvcwowmbxxnhsdmgxtvbfgnuqdpxennqglgmspbagvmjcmzmbsuacxlqfxjggrwsnbblnnwisvmpwwhomyjylbtedzrptejjsaiqzprnadkjxeqfdpkddmbzokkegtypxaafodjdwirynzurzkjzrkufsokhcdkajwmqvhcbzcnysrbsfxhfvtodqabvbuosxtonbpmgoemcgkudandrioncjigbyizekiakmrfjvezuzddjxqyevyenuebfwugqelxwpirsoyixowcmtgosuggrkdciehktojageynqkazsqxraimeopcsjxcdtzhlbvtlvzytgblwkmbfwmggrkpioeofkrmfdgfwknrbaimhefpzckrzwdvddhdqujffwvtvfyjlimkljrsnnhudyejcrtrwvtsbkxaplchgbikscfcbhovlepdojmqybzhbiionyjxqsmquehkhzdiawfxunguhqhkxqdiiwsbuhosebxrpcstpklukjcsnnzpbylzaoyrmyjatuovmaqiwfdfwyhugbeehdzeozdrvcvghekusiahfxhlzclhbegdnvkzeoafodnqbtanfwixjzirnoaiqamjgkcapeopbzbgtxsjhqurbpbuduqjziznblrhxbydxsmtjdfeepntijqpkuwmqezkhnkwbvwgnkxmkyhlbfuwaslmjzlhocsgtoujabbexvxweigplmlewumcone';
// 返回:wfdfw
PHP中文网
PHP中文网

认证0级讲师

全部回复(3)
大家讲道理
jsfunction fn1(s) {
    var ret = '';
    for (var i = 0, il = s.length; i < il; i++) {
        var tmp = [];
        tmp[i] = s[i];
        for (var indexLeft = i - 1, indexRight = i + 1;
            indexLeft >= 0 && indexRight < il;
            indexLeft--, indexRight++
        ) {
            if (s[indexLeft] !== s[indexRight]) break;
            tmp[indexLeft] = s[indexLeft];
            tmp[indexRight] = s[indexRight];
        }
        tmp = tmp.join('');
        if (tmp.length > ret.length) {
            ret = tmp;
        }
    }

    return ret;
}

function fn2(s) {
    var start = 0, length = 0;
    for (var i = 0, il = s.length; i < il; i++) {
        for (var indexLeft = i - 1, indexRight = i + 1;
            indexLeft >= 0 && indexRight < il;
            indexLeft--, indexRight++
        ) {
            if (s[indexLeft] !== s[indexRight]) break;
        }

        var tmpLength = indexRight - indexLeft - 1;
        if (tmpLength > length) {
            start = indexLeft + 1;
            length = tmpLength;
        }
    }

    return s.substr(start, length);
}

var str = 'dbakokabbbbbbb';

console.time('spend1');
console.log(fn1(str));
console.timeEnd('spend1');

console.time('spend2');
console.log(fn2(str));
console.timeEnd('spend2');
PHP中文网

原始代码帮你注释一下

var longestPalindrdome = function (s) {
    var t = s.split("").join("#");  // 第一,说是插,其实不是真的插入,只是写代码的是认为是插入了,而实际代码中不插
    var c = 1, e = 0, cs = 0;
    t = "~" + t + "#";

    for (var j = 1, lenj = t.length - 1; j < lenj; j++, c = 1) {
     /*通过前面的对比获得部分信息的,所以这个 c 可能大于1 C的来源是用这个公式得到的,其中f(i) 就是你说的 c 
      f(i) >= min { f(2j-i),f(j)-2(i-j) } ,for j<=i<= j+f(i)/2 */
        while (t[j + c] === t[j - c]){
            c++;
        }

        if (c > e) {
            e = c;
            cs = j;
        }

    }

    var result = t.slice(cs - e + 1, cs + e).replace(/#/g, "").replace(/~/g, ""); //这句后面那个替换也不需要了
    return result;
};
PHP中文网

答案莫名其妙被踩,已刪除。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号