[leetcode]5. 最長回文子串

題目描述:
給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。

  • 示例 1:
    輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。
  • 示例 2:
    輸入: "cbbd" 輸出: "bb"

笨辦法:
最初的想法還是暴力破解,但暴力破解的方法顯然代價很高。但在沒有其它更好方法的情況下,可以先試著把暴力破解的方法寫出來。關鍵是回文數的判定方法,假設存在字符串s為回文字符串,則s[0]=s[length-1]、s[1]=s[length-2]……。但是這種判定方式太過冗長,于是想到第二種判定方法s=s[::-1],即字符串反轉之后依然是自身。

聰明方法:
想到s=s[-1::-1],就突然反應出來可以用動態(tài)規(guī)劃(DP)來做,這不就是求s和s[::-1]的最大公共子串嗎。畫個矩陣就做出來了,具體的計算公式如下:

  • 當對應的字符相同時,當前公共子串的長度為:m[i-1][j-1]+1
  • 當對應的字符不同時,當前公共子串的長度為:0

還有個問題沒有考慮到:
如果字符串里正好包含兩個相互倒序的子串,將整個字符串倒序后,找到的最大公共子串可能是這兩個相互反序的子串。例如:字符串"aacdefcaa"中包含"aac"和"caa"兩個子串,整個字符串倒序后,最大公共子串為aac。
可以考慮排除這種情況,也就是每次檢測到最大公共子串的時候,檢驗這個子串是否為回文字符串,如果是才記錄,不是則丟棄。

超時的問題:
代碼總算是對了,但是超時了,DP的時間復雜度是O(n^2)。難道還有比DP時間復雜度更小的解法?還真有個Manacher's ALGORITHM,本篇先不討論。
可以對全部相同的子串或者循環(huán)子串單獨處理,提升處理速度,最終總算是通過了測試。但速度是相當的慢,明明總體思路和官方給出的思路是一致的啊,都用的DP,有空再研究下Manacher's ALGORITHM吧,據說時間復雜度是O(n)。

代碼如下:

import numpy as np
class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        n=len(s)
        m=np.zeros((n,n))
        sr=s[::-1]
        tmpl,maxl=0,0
        tmps,maxs="",""
        if s==sr:
            return s
        for i,vi in enumerate(s):
            for j,vj in enumerate(sr):
                if vi==vj:
                    if i>=1 and j>=1:
                        m[i][j]=m[i-1][j-1]+1
                    else:
                        m[i][j]=1
                # else:
                #     m[i][j]=0
                if m[i][j]>maxl:
                    tmpl=m[i][j]
                    tmps=s[int(i-tmpl+1):(i+1)]
                    # 檢驗子串是否為回文子串
                    if tmps[::-1]==tmps:
                        maxl=m[i][j]
                        maxs=tmps
        return maxs
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容