leetcode中有這麼一道題:
給定乙個字串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba"也是乙個有效答案。
示例 2:
輸入: "cbbd"
輸出: "bb"
回文串的定義我就不囉嗦了。對於這道題,我的第一反應是用動態規劃方法解。
假設字串s的長度為length,建立乙個length*length的矩陣dp。
dp[i][j]表示「以s[i]開始s[j]結尾的回文串的長度。如果這個字串不是回文串,讓dp[i][j]=0」。顯然,j>=i,只需往dp填j>=i的部分即可。
dp[i][j]的遞推公式可以這麼表述:
(1)首先對dp的對角線元素初始化為1,也就是當i==j時,dp[i][j]=1。
這很顯然,每個單獨的字元其實就是個長度為1的回文串。
(2)當j-i==1:
若s[i]==s[j],則dp[i][j]=2;否則dp[i][j]=0。
解釋:當j-i==1時,若s[i]==s[j],則s[i]和s[j]可以組成乙個長度為2的回文串。若s[i]!=s[j],顯然他們不可能組成回文串,dp[i][j]=0。
(3)當j-i>=2:
若s[i]==s[j]:若dp[i+1][j-1]>0,則dp[i][j]= dp[i + 1][j - 1] + 2;否則dp[i][j]= 0;
若s[i]!=s[j]:dp[i][j]=0。
解釋:如果s[i]==s[j],表明這個子串有可能是回文串。當去頭去尾後它是回文串時,就可以在去頭去尾的那個回文串長度基礎上+2,得到它的長度。如果去頭去尾後不是回文串,那這個子串一定不是回文串,回文串長度只能是0。
若s[i]!=s[j],顯然他們不可能組成回文串,dp[i][j]=0。
只需找到dp[i][j]的最大元素和它對應的i和j就可以得到結果「s中最長回文子串」。
另外還有乙個要注意的點:因為需要訪問dp[i+1][j-1],因此i是從大到小的,j是從小到大的。j從0到size-1,i從j-1到0。
貼上我的c++**:
1 classsolution16 }
17 int start = 0, max = 1;
18 for (int j = 0; j < size;j++)
26 else dp[i][j] = 0;
27 }
28 }
29 else dp[i][j] = 0;
30 if (dp[i][j]>max)
33 }
34 }
35 returns.substr(start, max);
36 }
37 };
時間複雜度和空間複雜度都為o(n^2),n為字串長度。
介紹了manacher'salgorithm——馬拉車演算法,可以在o(n)時間複雜度得到最長回文串。
最長回文字串
scanf s 輸入字串碰到空格或者tab就會停下來。此處可以使用fgets或者gets 另外注意標頭檔案cctype中的函式的巧妙使用,此處使用isalpha和toupper簡化了 此處列舉字串的中間位置,然後向倆邊擴充套件,節省了時間複雜度,注意向倆邊擴充套件時,奇數個和偶數個長度的區別。另外程...
最長回文字串
回文串定義 回文串 是乙個正讀和反讀都一樣的字串,比如 asddsa 或者 lovekevol 等等就是回文串。回文子串,顧名思義,即字串中滿足回文性質的子串。這裡我給出通過 列舉回文串的中間位置i,然後不斷向外擴充套件,直達有字元不相同。注意,這裡長度為奇數和偶數的處理方式是不一樣的。下面給出 這...
最長回文字串
時間限制 1000 ms 記憶體限制 65535 kb 難度 4 描述 輸入乙個字串,求出其中最長的回文子串。子串的含義是 在原串連續出現的字串片段。回文的含義是 正著看和倒著看是相同的,如abba和abbebba。在判斷是要求忽略所有的標點和空格,且忽略大小寫,但輸出時按原樣輸出 首尾不要輸出多餘...