package main.java.demo5;
/**
* 给你一个字符串 s,找到 s 中最长的回文子串。
*/
public class LongestPalindrome {
/**
* 解法思路:从字符0开始直到最后一个字符,
* 以该字符为中心向两边扩展,直到不能扩展为止.
* 注意:这里要分最开始的时候是一项还是两项,比如aba和abba.
*
* @param s
* @return
*/
public String longestPalindrome_1(String s) {
int length = s.length();
int[] currentResult = new int[2];
int[] result = new int[2];
int leftPoint = 0;
int rightPoint = 0;
char[] chars = s.toCharArray();
for (int i = 0; i < length - 1; i++) {
// 初始时左指针和右指针都指向当前选中的字符
leftPoint = rightPoint = i;
// 分别调用回文中单个字符在中间和两个相等的字符在中间的算法,求出最大回文的起止位置
int[] singleResult = getPalindrome(chars, leftPoint, rightPoint);
int[] doubleResult = getPalindrome(chars, leftPoint, rightPoint + 1);
// 比较当前位置中回文的最大长度作为currentLength代表当前位置回文最大值
int singleLength = singleResult[1] - singleResult[0];
int doubleLength = doubleResult[1] - doubleResult[0];
currentResult = singleLength > doubleLength ? singleResult : doubleResult;
// 根据当前最好结果和result比较并赋值,
int resultLength = result[1] - result[0];
int currentLength = currentResult[1] - currentResult[0];
if (currentLength > resultLength) {
result = currentResult;
}
}
// 返回结果
return s.substring(result[0], result[1] + 1);
}
private int[] getPalindrome(char[] chars, int leftPoint, int rightPoint) {
int[] result = new int[2];
while (leftPoint >= 0 && rightPoint < chars.length) {
if (chars[leftPoint] == chars[rightPoint]) {
result[0] = leftPoint;
result[1] = rightPoint;
} else {
return result;
}
leftPoint--;
rightPoint++;
}
return result;
}
/**
* 解法思路: 利用动态规划解决此问题,
* 递归方程为P(i,j) = P(i + 1, j - 1) && (Si == Sj)
* 递归方程结束条件为 P(i,i) = true 或 P(i,i+1) = (Si == Sj)
* @param s
* @return
*/
public String longestPalindrome_2(String s) {
int length = s.length();
int[] currentResult = new int[2];
// 当字符串长度小于等于1时,直接返回
if(length <= 1) {
return s;
}
// 创建二维数组用于存储回文起止位置的结果
boolean[][] result = new boolean[length][length];
// 将字符串中字符数量为1设置为true
for (int i = 0; i < length; i++) {
result[i][i] = true;
}
char[] chars = s.toCharArray();
// 对字符串进行遍历, 从字符数量为2 开始.
for (int subLen = 2; subLen <= length; subLen++) {
for (int leftPoint = 0; leftPoint < length - subLen + 1; leftPoint++) {
int rightPoint = leftPoint + subLen - 1;
if(chars[leftPoint] == chars[rightPoint]){
if(subLen == 2) {
result[leftPoint][rightPoint] = true;
} else {
result[leftPoint][rightPoint] = result[leftPoint + 1][rightPoint - 1];
}
if (result[leftPoint][rightPoint] == true) {
if (rightPoint - leftPoint > currentResult[1] - currentResult[0]) {
currentResult[0] = leftPoint;
currentResult[1] = rightPoint;
}
}
}
}
}
return s.substring(currentResult[0], currentResult[1] + 1);
}
}
11-04
938