題目要求:
* 給定字符串,求解最長回文子串
* 字符串最長為1000
* 存在獨一無二的最長回文字符串
求解思路:
* 回文字符串的子串也是回文,比如P[i,j](表示以i開始以j結束的子串)是回文字符串,
* 那么P[i+1,j-1]也是回文字符串。這樣最長回文子串就能分解成一系列子問題了。
* 這樣需要額外的空間O(N^2),算法復雜度也是O(N^2)。
* 首先定義狀態方程和轉移方程:
* P[i,j]=0表示子串[i,j]不是回文串。P[i,j]=1表示子串[i,j]是回文串。
* P[i,i]=1
* P[i,j]{=P[i+1,j-1],if(s[i]==s[j])
* =0 ,if(s[i]!=s[j])}
代碼:
1 public static String longestPalindrome(String s){ 2 if(s == null || s.length() == 1){ 3 return s; 4 } 5 int len = s.length(); 6 //flag[i][j]=true 表示子串i-j為回文字符串 7 boolean[][] flags = new boolean[1000][1000]; 8 int start = 0; 9 int maxlen = 0; 10 for(int i=0; i<len; i++){ 11 flags[i][i] = true; 12 //相鄰的兩個字符相同 13 if( i<len-1 && s.charAt(i) == s.charAt(i+1)){ 14 flags[i][i+1] = true; 15 start = i; 16 maxlen = 2; 17 } 18 } 19 20 //m代表回文子串長度,從3開始 21 for(int m = 3; m <= len; m++){ 22 for(int i = 0; i <= len-m; i++ ){ 23 //依次比較是否符合狀態轉移方程 24 int j = i+m-1; 25 if(flags[i+1][j-1] && s.charAt(i)==s.charAt(j)){ 26 flags[i][j] = true; 27 start = i; 28 maxlen = m; 29 } 30 } 31 } 32 33 //如果存在回文子字符串 34 if(maxlen >=2 ){ 35 return s.substring(start, start+maxlen); 36 } 37 //不存在則返回null 38 return null; 39 }