1. 程式人生 > >動態規劃實現迴文字串問題

動態規劃實現迴文字串問題

問題一:求一個字串的最大回文字串長度;

  1)思路:動態規劃;

  2)具體描述:設立一個長度len為字串str,用一個dp[len][len]的二維陣列來表示字串i-j下標所構成的子串的長度,經過迴圈計算之後我們返回最大回文子串的長度即可,即返回dp[0][len-1];

  3)dp陣列的具體實現:根據動態規劃自底向上的思想,從迴文子串到求出整個最長迴文字串,首先從str的結尾開始遍歷到str 的頭部,同時每一次記錄dp的初始值;如果str[i]==str[j],說明i-j為迴文字串,此時應該更新dp[i][j]的值;如果str[i]≠str[j],應該判斷dp[i+1][j]和dp[i][j-1]的大小,取出其中max作為最大長度更新dp[i][j]的值

  4)程式碼實現

 1     static int longestPalindrome1(String str) {
 2         int len = str.length();
 3         for (int i = len - 1; i >= 0; i--) {
 4             dp[i][i] = 1;
 5             for (int j = i+1; j < len; j++) {
 6                 if(str.charAt(i) == str.charAt(j)) {
 7                     dp[i][j] = dp[i + 1][j - 1] +2;
8 } else { 9 dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]); 10 } 11 } 12 } 13 return dp[0][len-1]; 14 }

  5)測試結果:測試字串12ABCBDABADBCBA34的最大回文串,我們可以看出最大回文串為ABCBDABADBCBAB,長度為13

  

問題二:將上述問題修改為輸出最長迴文子串

  1)我們知道,動態規劃最優解的子問題同樣也是最優解,即最長迴文字串的子串也是迴文串,假設p[i][j]是迴文字串,那麼p[i+1][j-1]也是迴文字串,這樣最長迴文字串就能夠分解成為一系列子問題來求解。

  2)程式碼實現

 1     static String longestPalindrome2(String str) {
 2         int len = str.length();
 3         int maxlen = 0, start = 0;
 4         for (int i = 0; i < str.length(); i++) {
 5             dp[i][i] = 1;
 6             if(i < len -1 && str.charAt(i) == str.charAt(i+1)) {
 7                 dp[i][i+1] = 1;
 8                 start = i;
 9                 maxlen = 2;
10             }
11         }
12         
13         for (int i = 3; i < str.length(); i++) { //分析整個串長度
14             for (int j = 0; j < len - i; j++) { //子串其實地址
15                 int m = i+j - 1; //子串結束地址
16                 if(dp[j+1][i-1] == 1 && str.charAt(i) == str.charAt(j)) {
17                     dp[j][i] = 1;
18                     maxlen = i;
19                     start = j;
20                 }
21             }
22         }
23         return str.substring(start,start+maxlen-1);
24     }

  2)測試輸入:同樣是將上述測試用例,測試字串12ABCBDABADBCBA34的最大回文串,我們可以看出最大回文串為ABCBDABADBCBAB