動態規劃實現迴文字串問題
阿新 • • 發佈:2018-12-01
問題一:求一個字串的最大回文字串長度;
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