服了,一道DP写一天,写出来的代码还巨烂
DP思路:
- 正序串和逆序串找最长公共子串,注意需另外判断子串是否为回文串,比如"abchkcba",这个很坑。
- dp数组记录正序串在i之前,逆序串在j之前的最长公共子串长度,公共子串以 [i][j] 处的char作为结束的,所以当 chararr[i] != adverse[j] 时,最长公共子串长度直接为0。
- dp时,if(chararr[i] == adverse[j]) dp[i][j] = dp[i-1][j-1] + 1;else不做处理。else这里一开始做错了,瞎搞,原因是不理解第2点写的dp思路。
- guide数组记录正序串在i之前的最长公共子串长度,只有dp[i][j]比原guide[i]大时才需替换,最后记录的是正序串在i之前和逆序串的全部的最长公共子串长度(公共子串是带 i 的,所以取公共子串时直接从 i 向前取就行了)。
- 字符串逆转时可以用 String reverse = new StringBuffer(s).reverse().toString();
class Solution {
public String longestPalindrome(String s) {
if(s.length() == 0) return s;
char[] adverse = new char[s.length()];
int tmp = s.length()-1;
char[] chararr = s.toCharArray();
for (int i = 0; i < adverse.length; i++) {
adverse[i] = s.charAt(tmp--);
System.out.print(adverse[i]);
}
System.out.println();
System.out.println();
int[][] dp = new int[s.length()][s.length()];
int[] guide = new int[s.length()];
//由实例4可知,应假定chararr为列,adverse为行
//初始化第一行
for (int i = 0; i < adverse.length; i++) {
if(adverse[i] == chararr[0]){
guide[0] = 1;
dp[0][i] = 1;
}
else
dp[0][i] = 0;
}
//初始化第一列
for (int i = 0; i < adverse.length; i++) {
if(chararr[i] == adverse[0])
dp[i][0] = 1;
else
dp[i][0] = 0;
}
for (int i = 1; i < s.length(); i++) {
for (int j = 1; j < s.length(); j++) {
//先i后j,i是chararr,j是adverse
if(chararr[i] == adverse[j]){
dp[i][j] = dp[i-1][j-1] + 1;
guide[i] = Math.max(dp[i][j], guide[i]);
// System.out.print(guide[i]+" ");
}
// else
// dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
System.out.println();System.out.println();
// for (int i = 0; i < s.length(); i++) {
// for (int j = 0; j < s.length(); j++) {
// if(j == s.length()-1)
// System.out.println(dp[i][j]+" ");
// else
// System.out.print(dp[i][j]+" ");
// }
// }
System.out.println();
int max = 0;
for (int i = 0; i < guide.length; i++) {
System.out.print(guide[i]+" ");
if(guide[i] > guide[max])
if(isHuiWen(s.substring(i+1-guide[i], i+1)))
max = i;
}
System.out.println();
System.out.println(max);
return s.substring(max+1-guide[max], max+1);
}
public boolean isHuiWen(String s){
System.out.println(s);
String reverse = new StringBuffer(s).reverse().toString();
if(reverse.equals(s)) return true;
else return false;
}
}