LeetCode #5 Longest Palindromic Substring - 刷題之旅
1 題目描述
找到最長的字串,該字串是回文的,也就是說,從左到右和從右到左是一樣的。
2 解法
2.1 暴力破解
1 | def isPalindrome(s: str, i: int, j: int) -> bool: |
2.2 由中心向外過展
從2.1的暴力破解法中有很多redundant computation。
- 如果
s[i:j]
是回文,那麼s[i+1:j-1]
往內的組合是回文 - 如果
s[i:j]
不是回文,那麼s[i-1:j+1]
往外擴展時,也不會是回文
也因此,你會發現,如果我們鎖定一個中心點,然後往外擴展,當發現不是回文時,就立刻換下一個中心點。這樣的時間複雜度是O(n^2)。
- O(N) 遍歷每個字元當作中心點
- O(N) 每個中心點擴展,最大擴展長度是O(N)
Time complexity: O(N^2)
- 最佳解法是O(N)當發現整個s不是回文時,立刻換下一個中心點。
- 最壞的狀況是O(N^2)
1 | def longestPalindrome(self, s: str) -> str: |
如果不想要太多重複的程式碼,也可以參考下面的寫法,只是有幾個注意的點:
- 在 getLen 的時候,要注意 -1 因為會多擴展一次後才發現不滿足
- 要注意
start = i - (cur - 1) // 2
是因為我們要找到回文的起始點,cur要先-1才可以同時滿足odd, even的情況- 例如
abba
的時候,i=1
的時候cur=4
,所以start = 1 - (4-1)//2 = 1 - 1 = 0
,這樣才可以取到abba
- 例如
1 | def longestPalindrome(self, s: str) -> str: |
2.3 O(n) Manacher’s Algorithm
我覺得這個算法非常複雜…我也不太懂,但是有興趣可以餐看這個影片Youtube |EP292Longest Palindromic Substring O(N) Manacher’s Algorithm
3 總結
這題沒有太多dp的影子在裡面,這題的關鍵在當你意識到回文的時候,從中間往外去擴展,這可以讓你從O(N^3)縮短成O(N^2)。這題的時間複雜度是O(N^2),空間複雜度是O(1)。
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Shannon's Blog 🐟 技術 | 生活 | 旅行! 如果你覺得我的文章有幫助,希望你可以到我的 github 給我一個 star ⭐️ Shannon Blog Repo
評論