最长回文子串
难度:中等
p1:通过中心向外扩充
//以每一个位置为中心向外扩散找最大子串
public String longestPalindrome(String s) {
int length = s.length();
int[] dp = new int[length];
int maxlen = 0;
String ans = "";
for(int i = 0; i < length; i++){
//因为中心可能有一个值或者两个值,要分情况
int len1 = lenPalindrome(s, i, i);
int len2 = lenPalindrome(s, i, i+1);
int len = Math.max(len1, len2);
if(maxlen < len){
maxlen = Math.max(maxlen, len);
ans = s.substring(i - (len-1)/2, i + len/2 + 1);
}
}
return ans;
}
//判断以 start,end为中心的字符串向外扩展回文的最大长度
public static int lenPalindrome(String s, int start, int end){
while(start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)){
start--;
end++;
}
return end - start - 1;
}
p2:动态规划
boolean保存[i,j]区间是否为回文
dp[i][j] = (dp[i+1][j-1])&&(s.charAt(i)==s.charAt(j))
边界值(长度为1或2时要单独考虑)
public String longestPalindrome(String s){
int length = s.length();
//dp保存从[i,j]区间内是否为回文字符串
boolean[][] dp = new boolean[length][length];
int maxlen = 0;
String ans = "";
for(int len = 1; len <= length; len++){ //注意<= length
for(int start = 0; start < length; start++){
int end = start + len - 1;
if(end >= length) break;
dp[start][end] = (len == 1 || len == 2 || dp[start+1][end-1]) && s.charAt(start) == s.charAt(end);
if(dp[start][end] && maxlen < len){
maxlen = len;
ans = s.substring(start, end+1);
}
}
}
return ans;
}
p3:将字符串反转,反转字符串和原字符串进行比较(最长公共子串),不过要注意(abcghjcba)此类字符串,所以每次比较要进行字符位置判断(反转后的公共字符位置与反转前比较)
public String longestPalindrome(String s) {
if (s.equals(""))
return "";
String origin = s;
String reverse = new StringBuffer(s).reverse().toString();
int length = s.length();
int[][] arr = new int[length][length];
int maxLen = 0;
int maxEnd = 0;
for (int i = 0; i < length; i++)
for (int j = 0; j < length; j++) {
if (origin.charAt(i) == reverse.charAt(j)) {
if (i == 0 || j == 0) {
arr[i][j] = 1;
} else {
arr[i][j] = arr[i - 1][j - 1] + 1;
}
}
/**********修改的地方*******************/
if (arr[i][j] > maxLen) {
int beforeRev = length - 1 - j;
if (beforeRev + arr[i][j] - 1 == i) { //判断下标是否对应
maxLen = arr[i][j];
maxEnd = i;
}
/*************************************/
}
}
return s.substring(maxEnd - maxLen + 1, maxEnd + 1);
}