LeetCode 題解 | 5. 最長迴文子串
來自專欄領扣(LeetCode)9 人贊了文章
題目描述:
給定一個字元串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為1000。
示例 1:
輸入: "babad"輸出: "bab"注意: "aba" 也是一個有效答案。
示例 2:
輸入: "cbbd"輸出: "bb"
最長迴文子串 - LeetCode (中國)
摘要:
這篇文章是為中級讀者而寫的。它介紹了迴文,動態規劃以及字元串處理。請確保你理解什麼是迴文。迴文是一個正讀和反讀都相同的字元串,例如, 是迴文,而 不是。
方法一、最長公共子串:
常見錯誤
有些人會忍不住提出一個快速的解決方案,不幸的是,這個解決方案有缺陷(但是可以很容易地糾正):
反轉 ,使之變成 。找到 和 之間最長的公共子串,這也必然是最長的迴文子串。
這似乎是可行的,讓我們看看下面的一些例子。
例如, , :
以及 之間的最長公共子串為 ,恰恰是答案。
讓我們嘗試一下這個例子: ,:
以及 之間的最長公共子串為 ,顯然,這不是迴文。
演算法
我們可以看到,當 的其他部分中存在非迴文子串的反向副本時,最長公共子串法就會失敗。為了糾正這一點,每當我們找到最長的公共子串的候選項時,都需要檢查子串的索引是否與反向子串的原始索引相同。如果相同,那麼我們嘗試更新目前為止找到的最長迴文子串;如果不是,我們就跳過這個候選項並繼續尋找下一個候選。
這給我們提供了一個複雜度為 動態規劃解法,它將佔用 的空間(可以改進為使用 的空間)。請在這裡閱讀更多關於最長公共子串的內容。
方法二、暴力法:
很明顯,暴力法將選出所有子字元串可能的開始和結束位置,並檢驗它是不是迴文。
複雜度分析
- 時間複雜度:,假設 是輸入字元串的長度,則 為此類子字元串(不包括字元本身是迴文的一般解法)的總數。因為驗證每個子字元串需要 的時間,所以運行時間複雜度是 。
- 空間複雜度: 。
方法三、動態規劃:
為了改進暴力法,我們首先觀察如何避免在驗證迴文時進行不必要的重複計算。考慮 這個示例。如果我們已經知道 是迴文,那麼很明顯, 一定是迴文,因為它的左首字母和右尾字母是相同的。
我們給出 的定義如下:
- ,如果子串 是迴文子串
- ,其他情況
因此,
基本示例如下:
這產生了一個直觀的動態規劃解法,我們首先初始化一字母和二字母的迴文,然後找到所有三字母迴文,並依此類推…
複雜度分析
- 時間複雜度:, 這裡給出我們的運行時間複雜度為 。
- 空間複雜度:, 該方法使用 的空間來存儲表。
補充練習
你能進一步優化上述解法的空間複雜度嗎?
方法四、中心擴展演算法:
事實上,只需使用恆定的空間,我們就可以在 的時間內解決這個問題。
我們觀察到迴文中心的兩側互為鏡像。因此,迴文可以從它的中心展開,並且只有 個這樣的中心。
你可能會問,為什麼會是 個,而不是 個中心?原因在於所含字母數為偶數的迴文的中心可以處於兩字母之間(例如 的中心在兩個 之間)。
public String longestPalindrome(String s) { int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > end - start) { start = i - (len - 1) / 2; end = i + len / 2; } } return s.substring(start, end + 1);}private int expandAroundCenter(String s, int left, int right) { int L = left, R = right; while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) { L--; R++; } return R - L - 1;}
複雜度分析
- 時間複雜度:, 由於圍繞中心來擴展迴文會耗去 的時間,所以總的複雜度為 。
- 空間複雜度: 。
方法五、Manacher 演算法:
還有一個複雜度為 的 Manacher 演算法,你可以在這裡找到詳盡的解釋。然而,這是一個非同尋常的演算法,在45分鐘的編碼時間內提出這個演算法將會是一個不折不扣的挑戰。但是,請繼續閱讀並理解它,我保證這將是非常有趣的。
推薦閱讀:
※1-12 關於改行的問詢
※Kafka(一):基礎概念
※自從學了計算機網路,室友終於不在半夜打遊戲了-- ping/ICMP學以致用
※計算機-編碼 解碼
TAG:LeetCode領扣 | 計算機科學 | 計算機專業 |