LeetCode.5-パリンドローム最長の部分文字列(最長回文サブストリング)

免責事項:この記事はブロガーオリジナル記事ですが、許可ブロガーなく再生してはなりません。https://blog.csdn.net/codeMas/article/details/90746896

これは、喜びと喜びの最初の本である342、最初の更新366ピアンオリジナル

01の質問と準備ができて見えます

LeetCodeアルゴリズムはミディアム・レベルの質問質問3(全体的なタイトル第5号)で、今日導入されます。文字列sを考えると、最も長いサブストリングパリンドロームを見つけることです。あなたは1000秒の最大の長さと仮定することができます。例えば:

入力:「babad」
出力:「BAB」
注:「ABA」は有効な答えがあります。

入力: "cbbd"
出力: "BB"

02第一溶液

暴力的なソリューションを提供します。
結果として、最も長いサブストリングの出力を取るサブストリング回文かどうかを決定するすべてのサブストリングを使用して、2つのサイクルを取ら。
市のこの複雑なソリューション時間O(N^3)スペースの複雑市O(1)

public String longestPalindrome(String s) {
    int max = 0, n = s.length();
    String result = "";
    for (int i=0; i<n; i++) {
        for (int j=i+1; j<=n; j++) {
            String tem = s.substring(i,j);
            if (isPalindrome(tem)) {
                if (j-i > max) {
                    max = j-i;
                    result = tem;
                }
            }    
        }
    }
    return result;
}

public boolean isPalindrome(String s){
    int left = 0, right = s.length()-1;
    while (left < right) {
        if (s.charAt(left) != s.charAt(right)) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

03第二の溶液

また、帰りの中間に左と中間の右側の左右にテキストを変更することがあります。

それは両側、例えばパリンドローム「BAB」の中心を見つけるために、現在の文字に関して、異形パリンドロームの場合、このパリンドロームの長さの考慮事項は、偶数奇数であるか、または、パリンドローム形は偶数、最初の2つの文字がある場合、および2つの文字は、現在の文字等しく、左右、例えばパリンドローム「アバ」を見つけるために、隣接する中央の文字である必要があります。

このソリューションの時間複雑性はあるO(N^2)宇宙の複雑市O(1)

public String longestPalindrome2(String s) {
    if (s.length() < 2) {
        return s;
    }
    int n = s.length(), start = 0, end = 0;
    for (int i=0; i<n-1; i++) {
        int len = helper(s, i, i);
        int len2 = helper(s, i, i+1);
        int len3 = Math.max(len, len2);
        if (len3 > end - start) {
            start = i - (len3-1)/2;
            end = i + len3/2;
        }
    }
    return s.substring(start, end+1);
}

/**
 * 以当前字符为中心向左右两边扩散,寻找回文子串
 * @param s 字符串
 * @param left 起始索引
 * @param right 结束索引
 * @return 回文子串长度
 */
public int helper(String s, int left, int right) {
    int n = s.length(), L = left, R = right;
    while (L >= 0 && R < n && s.charAt(L) == s.charAt(R)) {
        // 继续向左寻找
        L--;
        // 继续向右寻找
        R++;
    }
    return R - L -1;
}

04第三の溶液

動的プログラミングアルゴリズムは、時間のためのスペースを使用して、第一の溶液の改良です。
このソリューションの時間複雑性はあるO(N^2)宇宙の複雑市O(N^2)

public String longestPalindrome3(String s) {
        if (s.length() < 2) {
            return s;
        }
        int n = s.length(), start = 0, end = 0;
        int maxLen = 0;
        // dp[j][i]表示子串[j,i]是回文
        boolean[][] dp = new boolean[n][n];
        // 右边界
        for (int i=0; i<n; i++) {
            // 左边界
            for (int j=i; j>=0; j--) {
                if (i == j) {
                    dp[j][i] = true;
                } else if (s.charAt(i) == s.charAt(j)) {
                    // 回文中至少3个字符
                    if (j < i-1) {
                        dp[j][i] = dp[j+1][i-1];
                    } else {
                        dp[j][i] = true;
                    }
                } else {
                    dp[i][j] = false;
                }
                // 比较最大值,并重新赋值
                if (i-j+1 > maxLen && dp[j][i]) {
                    maxLen = i-j+1;
                    start = j;
                    end = i;
                }
            }
        }
        return s.substring(start, end+1);
    }

05第溶液

馬車車のアルゴリズム(Manacherのアルゴリズム)は、フォーラムから、これは、時間の複雑さがに縮小されて、私はこのアルゴリズムを聞いたの初めてですO(N)、非常に強力であり、そしてそれに続くこのアルゴリズムについての詳細を学ぶために時間がかかります。

public String longestPalindrome4(String s) {
    String T = preProcess(s);
    int n = T.length();
    int[] P = new int[n];
    int C = 0, R = 0;
    for (int i = 1; i < n - 1; i++) {
        int i_mirror = 2 * C - i;
        if (R > i) {
            P[i] = Math.min(R - i, P[i_mirror]);
        } else {
            P[i] = 0;
        }
        while (T.charAt(i + 1 + P[i]) == T.charAt(i - 1 - P[i])) {
            P[i]++;
        }
        if (i + P[i] > R) {
            C = i;
            R = i + P[i];
        }
    }
    int maxLen = 0;
    int centerIndex = 0;
    for (int i = 1; i < n - 1; i++) {
        if (P[i] > maxLen) {
            maxLen = P[i];
            centerIndex = i;
        }
    }
    int start = (centerIndex - maxLen) / 2; 
    return s.substring(start, start + maxLen);
}

/**
 * 
 * @param s
 * @return
 */
public String preProcess(String s) {
    int n = s.length();
    if (n == 0) {
        return "^$";
    }
    String ret = "^";
    for (int i = 0; i < n; i++) {
        ret += "#" + s.charAt(i);
    }
    ret += "#$";
    return ret;
}

06まとめ

テーマ別アルゴリズムが連続しているより半年以上日間、特集記事のアルゴリズム211件の +記事、公衆番号]ダイアログボックスの返信[ データ構造とアルゴリズム ]、[ アルゴリズム ]、[ データ構造の記事コレクションのシリーズを得るために、キーワードのいずれか] 。

それは、すべてだあなたは何か良い解決策のアイデア、提案やその他の問題がある場合、あなたは以下のコメントを交換することができ、親指、メッセージ転送およびサポートは、私にとっての最大の報酬です!

おすすめ

転載: blog.csdn.net/codeMas/article/details/90746896