1. 程式人生 > >LeetCode - 5 - Longest Palindromic Substring

LeetCode - 5 - Longest Palindromic Substring

ems nbsp 偶數 運行時 ges style string -1 lee

題目

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

技術分享

解法

一、循環搜索

對於每一個字符,往後搜索,遇到相同字符,開始判斷是否回文串,若是回文串則與當前最長回文串的長度比較,若更長,則更新最長回文串。

顯然是三層循環:第一層確定回文串起始位置,第二層確定回文串終止位置,第三層判斷是否是回文串。

代碼也比較簡潔,可是循環太多。

    public String longestPalindrome(String s) {
        String maxString = null;
        int maxLength = 0;
        
for (int i = 0, left = i; i < s.length(); i++) { for (int j = i, right = j; j < s.length(); j++, left = i, right = j) { while (left < s.length() && right >= 0 && left < right && s.charAt(left) == s.charAt(right)) { left
++; right--; } if (left >= right && j - i + 1 > maxLength) { maxLength = j - i + 1; maxString = s.substring(i, j + 1); } } } return maxString; }

循環搜索,時間復雜度O(n3),運行時間約為 TLE

二、向外查找

對於每一個字符,假定它(回文串長度為奇數)或者它和它的右面字符(回文串長度為偶數)是回文串,那麽我們只需要向外擴張,直到它不是回文串。

該算法其奧妙在於假定和向外擴張,而不是盲目搜索。

    private int start;
    private int maxLength;

    public String longestPalindrome(String s) {
        if (s.length() == 0) return "";
        for (int i = 0; i < s.length(); i++) {
            findPalindrome(s, i, i);
            findPalindrome(s, i, i + 1);
        }
        return s.substring(start, start + maxLength);
    }

    private void findPalindrome(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        if (right - left - 1 > maxLength) {
            start = left + 1;
            maxLength = right - left - 1;
        }
    }

向外查找,時間復雜度O(n2),運行時間約為 17 ms

總結

有的時候思路要放開,不要太計算機思維(搜索),有時也要像現實一樣思考。

LeetCode - 5 - Longest Palindromic Substring