Longest Palindromic Substring - 一題多解

題意是尋找一個字符串的最大回文字串,最簡單的是n3方的算法,由於字符串最大長度爲1000,所以這個方法很危險而且不科學。

緊接着想到的是一個n方的算法:迴文子串是從中間向兩邊產生的,那麼對於每個字符考察這個字符往外的所有可能不就可以找到以這個字符爲中心的最長迴文子串了嗎?當然要考慮偶數的情況,即那個中心不在字母上,而這種情況的字符又一定滿足中心的兩個字符是相等的。所以在第一遍尋找奇數最長迴文字符的時候記錄下有可能形成偶數迴文字符的數組下標,統一規定爲兩個字母下標較小的那個。

按照以上想法編碼AC如下:

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         string resstring;
 5         int maxlen=0;
 6         int maxindex=0;
 7         int n=s.length();
 8         int doublestring[1002];
 9         if(n==1)
10             return s;
11         for(int i=0;i<n;i++)
12         {
13             int index=i;int delt=1;
14             if(index-delt>=0&&s[index-delt]==s[index])
15                 doublestring[index-1]=1;
16             if(index+delt<n&&s[index+delt]==s[index])
17                 doublestring[index]=1;
18             while(index-delt>=0&&index+delt<n){
19                 if(s[index-delt]==s[index+delt])
20                 {
21                     if(delt*2+1>maxlen)
22                     {
23                         maxlen=delt*2+1;
24                         maxindex=index;
25                     }
26                     delt++;
27                 }
28                 else
29                     break;
30             }
31         }
32         int resa=maxlen;
33 
34 
35         for(int i=0;i<n;i++)
36         {
37             if(doublestring[i]!=0)
38             {
39                 int index1=i;
40                 int index2=i+1;
41                 int delt=0;
42                 while(index1-delt>=0&&index2+delt<n){
43                     if(s[index1-delt]==s[index2+delt])
44                     {
45                         if(delt*2+2>maxlen)
46                         {
47                             maxlen=delt*2+2;
48                             maxindex=index1;
49                         }
50                         delt++;
51                     }
52                     else
53                         break;
54                 }
55             }
56         }
57         if(maxlen==resa)
58         {
59             int start=maxindex-(maxlen-1)/2;
60             resstring.append(s,start,maxlen);
61         }
62         else
63         {
64             int start=maxindex-(maxlen-2)/2;
65             resstring.append(s,start,maxlen);
66         }
67         //cout<<resstring<<endl;
68         return resstring;
69     }
70 };

這個方法有幾個需要注意的地方:

1.對於字符數目爲1的字符,直接返回不需進行處理。

2.在第一遍尋找奇數迴文的時候,delt爲1時不要在循環裏面判斷是否有對稱的結構,如果在裏面對於“abb”這種樣例就無法通過

3.在第二遍尋找偶數迴文的時候,delt應該從0開始,而非從1開始,這樣才能判斷出“bb”的樣例。

4.C++的string字符串的append函數好方便,起始位置start,長度n給出,可以直接複製。

 

以上是我做這個題目的方法,我估計這個題目可以用動態規劃解決,想了一會未果。動態規劃真是腦力活,自己做的動規也比較少。

http://blog.csdn.net/feliciafay/article/details/16984031

這裏有一篇介紹這個問題動態規劃解法,至於他提到的O(n)方法。。不敢細看。

另外關於最長迴文字串流行的解法是使用後綴樹這個數據結構來做。

關於後綴樹應用在這個問題的介紹附一個靠譜鏈接:

http://blog.csdn.net/g9yuayon/article/details/2574781

大致思路是使用後綴樹然後找LCA(最近公共祖先),我估計把這個搞明白也要一會,還是繼續先刷題吧。

裏面還提到了graphviz這個畫圖工具,好像比visio畫程序圖更好用的樣子。

http://www.graphviz.org/

隨意看了看這方面的介紹,發現用這個Drawing graphs with dot文檔入門比較靠譜。

 

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