1. 程式人生 > >最長迴文子字串(Longest Palindromic Substring)

最長迴文子字串(Longest Palindromic Substring)

Given a string S, find thelongest palindromic substring in S. You may assume that the maximumlength ofS is 1000, and there exists one unique longest palindromicsubstring.

給定一個字串S,在S中找到最長的迴文字串,你可以假設S的最長長度為1000,而且只存在唯一的最長迴文字串。

思路:一般而言我們一段字串判斷是否迴文,我們用兩個遊標分別放在字串的頭部和尾部,然後兩個遊標相向同速移動,在移動的過程中出現字元不相同的時,該字串就不是迴文的,否則就是迴文的。

然而在本題目中如果還是要用這樣的思路去解決問題,那麼我們首先要找到的是第一對相同的字元,然後根據前面描述的方法,判斷該範圍內的字串是否為迴文字串,如果是,跟當前記錄的最大長度作比較,決定當前找到的最長迴文字串的值,然後再找下一對相同的字元,再去判斷是否迴文……以此類推。

很顯然,我們要找到所有的相同字元對的時間複雜度已經是O(n^2),再加上判斷迴文字串的時間,如果字串長一些的話,要算出結果是很耗時間的。所有我們需要找一種更為有效的方法。

判斷迴文我們可以從最中間的字元出發,然後向兩邊拓展,那麼這樣掃描字串的時間複雜度就是O(n),向外拓展直至迴文不成立,然後記錄最長的迴文字串,這次整個演算法的時間複雜度就大大降下來了。

程式碼如下:

public class Solution {
    public String findPalindrome(String s, int left, int right) {
        int n = s.length();
        int l = left;
        int r = right;
        while (l >= 0 && r <= n - 1 && s.charAt(l) == s.charAt(r)) {
            l--;
            r++;
        }
        return s.substring(l + 1, r);
    }

    public String longestPalindrome(String s) {
        int n = s.length();
        if (n<=1) return s;

        String longest = "";

        String str;
        for (int i=0; i<n-1; i++) {
            str = findPalindrome(s, i, i);
            if (str.length() > longest.length()){
                longest = str;
            }
            str = findPalindrome(s, i, i + 1);
            if (str.length() > longest.length()){
                longest = str;
            }
        }

        return longest;
    }
}