200 · Longest Palindromic Substring - LintCode

# Description

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.)

# Example

Example 1:

Input:"abcdzdcab"
Output:"cdzdc"

Example 2:

Input:"aba"
Output:"aba"

# Challenge

O(n2) time is acceptable. Can you do it in O(n) time.

# Solution

# brute force solution

時間複雜度是 O (n^3) , n 為字符串長度
空間複雜度是 O (1), 只用到常數個臨時變量

public class Solution {
    /**
     * @param s: input string
     * @return: a string as the longest palindromic substring
     */
    public String longestPalindrome(String s) {
        // 暴力解
        int maxLen = 1;
        int start = 0;
        for (int i = 0; i < s.length() - 1; i++){
            for (int j = i + 1; j < s.length(); j++){
                if (j - i + 1 > maxLen && validPralindromic(s.toCharArray(), i, j)){
                    maxLen = j - i + 1;
                    start = i;
                }
            }
        }
        return s.substring(start, start + maxLen);
    }
    private boolean validPralindromic(char[] charArray, int left, int right){
        while (left < right){
            if (charArray[left] != charArray[right]){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

# 中心擴散 enumeration

  • 枚舉所有可能能回文子串的中心位置
  • 要考慮回文子串的中心的奇偶性;中心可能是一個字符,或兩個相鄰的字符
  • 記錄最長回文字串的相關變量
public class Solution {
    /**
     * @param s: input string
     * @return: a string as the longest palindromic substring
     */
    public String longestPalindrome(String s) {
        if (s.length() < 2){
            return s;
        }
        int maxlen = 1;
        int begin = 0;
        char[] charArray = s.toCharArray();
   
        
        for (int i = 0; i < s.length(); i++){
            int oddLen = expandCenter(charArray, i, i);
            int evenLen = expandCenter(charArray, i, i + 1);
            
            int charlen = Math.max(oddLen, evenLen);
            if (charlen > maxlen){
                maxlen = charlen;
                // 中心點,減去 字符串長度 - 1 的一半,
                // ##@@center@@##
        // index:  0123  4   5678
                // 4 - (5 - 1) / 2 = 2 (第一個 @的位置)
                begin = i - (maxlen - 1) / 2;
            }
        }
        return s.substring(begin, begin + maxlen);
 
    }
    public int expandCenter(char[] charArray, int left, int right){
        while (left >= 0 && right < charArray.length){
            if (charArray[left] != charArray[right]){
                break;
            }
            left--;
            right++;
        }
        // 退出 while 時 #xxxxx# 
        //       left       right 會在 #的位置
        return right - left - 1;  
    }
}

# 另一個寫法

public class Solution {
    /**
     * @param s: input string
     * @return: a string as the longest palindromic substring
     */
    public String longestPalindrome(String s) {
        if (s == null || s.length() < 2) return s;
        int maxLen = 0;
        String result = null;
        for (int center = 0; center < s.length(); center++){
                int start = center, end = center;
                while (start >= 0 && end < s.length()){
                    if (s.charAt(start) != s.charAt(end)){
                        break;
                    }
                    int newLen = end - start + 1;
                    if (newLen > maxLen){
                        maxLen = newLen;
                        result = s.substring(start, end + 1);
                    }
                    start--;
                    end++;
                }
                   int left = center, right = center + 1;
                   while (left >= 0 && right < s.length())
                   {
                    if (s.charAt(left) != s.charAt(right)){
                        break;
                    }
                    int newLen = right - left + 1;
                    if (newLen > maxLen){
                        maxLen = newLen;
                        result = s.substring(left, right + 1);
                    }
                    left--;
                    right++;
                }
            }
            return result;
        }
    }