LeetCode 5日目

LeetCode0005

  • 文字列sを考えると、最も長い部分文字列パリンドロームを見つけることです。あなたは1000秒の最大の長さと仮定することができます。
  • 例1:
  • 入力: "babad"
  • 出力: "BAB"
  • 注:「ABA」は有効な回答であるが、我々は唯一の出力条件を満たすために、最初の文字列。

思考

  • センターの拡張方法:公式サイトからLeetCodeこの記述を、実際には、単に一定のスペースを使用して、我々はOでこの問題を解決することができる(N ^ 2)時間。私たちは、双方が回文の中央の鏡像であることを観察しました。このように、その中心から展開することがパリンドローム、及びのみ2N-1このようなセンター。代わりに、n個の中心の、1ヶ月-あなたはなぜ2Nで、求めることができますか?その理由は、文字の数が偶数パリンドロームの中心に含まれるように、2つの文字(例えば中心「アバ」二「B」との間)の間とすることができるということです。
  • 公式の文言によると、我々はそれが一度延長奇数回文文字列センター、であると仮定すると、文字中心である必要があり、それは一度延長しても回文文字列の中心部、であると仮定します。奇数および偶数シリーズ2つのパリンドローム配列の文字列の長さ、最終確認回文配列の最大長さを比較します。ここでは、公式センターの拡張メソッドの外観を改善するために、アルゴリズム先に馬車車のアイデアを借ります。我々二つの中間インサートの各「ABCBA」奇数列のような形、例えば「#」などの特殊文字は、「アバ」可変「## B#、C#B ##」となる入力文字列「### B#Bが#」にした後、それらは奇数系列であるので、奇数列の中央のみが最大サブストリングを取得するために計算することができるように、我々が展開し、長さは、サブストリングを置換する、2で割った値特殊文字は、ストリングの最大アウトを取得します。
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function (s) {
    if (s.length === 0) return '';
    let sp = '#';
    let str = sp + s.split('').join(sp) + sp;
    let maxRadius = -1;
    let maxCenter = -1;
    for (let i = 0, lens = str.length; i < lens; i++) {
        let radius = expandAroundCenter(str, i);
        if (radius > maxRadius) {
            maxRadius = radius;
            maxCenter = i;
        }
    }

    return s.slice(maxCenter / 2 - maxRadius / 2 + 1, maxCenter / 2 + maxRadius / 2);
};

function expandAroundCenter(s, center) {
    let radius = 1;
    let lens = s.length;
    let left, right;
    do {
        left = center - radius;
        right = center + radius;
        if (left < 0 || right > lens - 1) break;
        if (s[left] === s[right]) {
            radius++;
        } else {
            break;
        }
    } while (true);
    return radius;
}
  • 我々はn個の文字列の文字列の長さに延長されますので、その最悪の場合には、我々は奇妙なパリンドロームとして2(最初の文字列の公式ウェブサイトを比較しない書き込みの数の比率を比較して、2N + 1でありますセンター、偶数回文文字列の中心として1)のn文字2N倍の速さの合計数は、我々はさらにそれn個の中に、半分の時間を最適化することができますか?
  • 改善点:最大の回文文字列がある場合に、想像するのは簡単です、あなたがの両端に、文字列の中央から開始することができますので、必ず最大の文字列を最初に発見し、中心から外側に向かって展開を開始するには、最大の回文文字列を検索し拡大し、あなたは、i番目のを見つけたときに最大の現在の文字列よりも大きいことは不可能である最大半径は、されている場合は、文字列の残りの部分は十分でないとき、それが終了します。コードは以下の通りであります:
/**
 * @param {string} s
 * @return {string}
 */
var longestPalindrome = function (s) {
    if (s.length === 0) return '';
    let sp = '#';
    let str = sp + s.split('').join(sp) + sp;
    let maxRadius = -1;
    let maxCenter = -1;
    let lens = str.length;
    let middle = Math.floor(lens / 2);
    for (let i = middle; i < lens; i++) {
        if (lens - i < maxRadius) break;
        let radius = expandAroundCenter(str, i);
        if (radius > maxRadius) {
            maxRadius = radius;
            maxCenter = i;
        }
    }

    for (let i = middle; i > -1; i--) {
        if (i < maxRadius - 1) break;
        let radius = expandAroundCenter(str, i);
        if (radius > maxRadius) {
            maxRadius = radius;
            maxCenter = i;
        }
    }

    return s.slice(maxCenter / 2 - maxRadius / 2 + 1, maxCenter / 2 + maxRadius / 2);
};

function expandAroundCenter(s, center) {
    let radius = 1;
    let lens = s.length;
    let left, right;
    do {
        left = center - radius;
        right = center + radius;
        if (left < 0 || right > lens - 1) break;
        if (s[left] === s[right]) {
            radius++;
        } else {
            break;
        }
    } while (true);
    return radius;
}
  • 私たちは、時間が通常の方法の半分に削減されている見ることができます。

2つのコミットの時間と空間の複雑さ

  • Manacher(馬車車)アルゴリズム:Manacherのアルゴリズムアルゴリズムが1975年に発明のManacherと呼ばれる人によって、文字列のリニア方式最長の回文構造部分文字列を検索するために使用されている馬車、このアプローチの最大の貢献は、ということですリニアO(n)を強化する時間複雑。

おすすめ

転載: www.cnblogs.com/zenronphy/p/12169239.html