【LeetCode】5. Longest Palindromic Substring(C++)
阿新 • • 發佈:2018-12-21
題目:
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: “babad”
Output: “bab”
Explanation: “aba” is also a valid answer.
Example 2:
Input: “cbbd”
Output: “bb”
理解:
本題要求尋找最長的迴文子串。
迴文子串有個很重要的性質,就是若一個串是迴文的,則給其兩側分別新增一個相同的字元,得到的仍然是迴文串。
有點可惜,有上面的思路,但是還是看了別人的才把具體實現寫出來。
因此,可以根據上面的性質,從每一個字元開始擴充套件。注意要把長度為奇數和偶數的分開來判斷。
複雜度:
- 時間複雜度:。遍歷一遍字串,每個位置要向兩邊擴充套件,因此是平方複雜度。
- 空間複雜度:。
實現1:
class Solution { int expandAroundCenter(const string& s, int l, int r) { while (l >= 0 && r < s.size() && s[l] == s[r]) { --l; ++r; } return r - l - 1; } public: string longestPalindrome(string s) { if (s.size() <= 1) return s; int lenMax = 0; int start = -1; for (int i = 0; i < s.size(); ++i) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = max(len1, len2); if (len > lenMax) { start = i - (len - 1) / 2; lenMax = len; } } return s.substr(start, lenMax); } };
還有另外一種實現,通過跳過重複字元,可以避免分奇偶的兩次判斷。
實現2:
注意全部字母相同的字串無論奇偶都是迴文串。
下面的實現巧妙的避開了分奇偶的判斷。先找到從j開始的重複單個字元子串,然後再向兩邊擴充套件即可。j為重複字元的開始,k為結束。
class Solution { public: string longestPalindrome(string s) { if (s.empty()) return ""; if (s.size() == 1) return s; int min_start = 0, max_len = 1; for (int i = 0; i < s.size();) { if (s.size() - i <= max_len / 2) break; int j = i, k = i; while (k < s.size() - 1 && s[k + 1] == s[k]) ++k; // Skip duplicate characters. i = k + 1; while (k < s.size() - 1 && j > 0 && s[k + 1] == s[j - 1]) { ++k; --j; } // Expand. int new_len = k - j + 1; if (new_len > max_len) { min_start = j; max_len = new_len; } } return s.substr(min_start, max_len); } };
還有dp和另一種演算法,看完電影回來補。fantastic beasts, I’m coming.