[LeetCode系列] 最長迴文子串問題

給定字符串S, 找到其子串中最長的迴文字符串.
 

反轉法: 反轉S爲S', 找到其中的最長公共子串s, 並確認子串s在S中的下標iS與在S'中的下標iS'是否滿足式: length(S) = iS + iS' + length(s). 如果滿足則s爲搜索結果, 如果不滿足我們就繼續搜索.

 
DP解法:
定義 P[i][j] = true  <-> Si...Sj是迴文串, 否則爲false;
則有 P[i+1][j-1] = true && Si = Sj <-> P[i][j] = true;
基本的情況則是 P[i][i] = true 以及 P[i][i+1] = (Si == Si+1)
從而我們可以在平方時間內構造和搜索完成, 並使用平方的空間.
 
 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         if (s.length() <= 1) return s;
 5         // DP solution
 6         bool P[1000][1000] = {false};
 7         int start = 0;
 8         int maxLen = 0;
 9         for (int i = 0; i < s.length(); i++) {
10             P[i][i] = true;
11         }
12         for (int i = 0; i < s.length() - 1; i++) {
13             if (s[i] == s[i+1]) {
14                 P[i][i+1] = true;
15                 start = i;
16                 maxLen = 2;
17             }
18         }
19         for (int len = 3; len <= s.length(); len++) {
20             for (int i = 0; i < s.length() - len + 1; i++) {
21                 int j = i + len - 1;
22                 if (s[j] == s[i] && P[i+1][j-1]) {
23                     P[i][j] = true;
24                     start = i;
25                     maxLen = len;
26                 }
27             }
28         }
29         return s.substr(start, maxLen);
30     }
31 };
 
中心法:
一個迴文總是以某個字符爲中心展開的, 這樣的中心共有2N-1個(包括2個字符中間的"空白").
考慮到從中心開始拓展迴文字符需要消耗O(N)次, 所以總的時間複雜度是O(N2).
 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         if (s.length() <= 1) return s;
 5         string longest = s.substr(0, 1);
 6         // Center Solution
 7         for (int i = 0; i < s.length() - 1; i++) {
 8             string res = expandFromCenter(s, i, i);
 9             if (res.length() > longest.length()) longest = res;
10             res = expandFromCenter(s, i, i+1);
11             if (res.length() > longest.length()) longest = res;
12         }
13         return longest;
14     }
15     
16     string expandFromCenter(string s, int l, int r) {
17         while (l >= 0 && r < s.length() && s[l] == s[r]) {
18             l--;
19             r++;
20         }
21         return s.substr(l+1, r-l-1);
22     }
23 };

 

Manacher法: 線性時間解法, 比較複雜, .

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章