题目描述:给定一个字符串,计算出字符串里的最长回文子串。
回文:aba,aa,a,aabb,abbba,abba这些都是回文,比较好理解。
下面是解法: 解法一:动态规划
class Solution {
public String longestPalindrome(String s) {
//边界条件判断
if(s.length() < 2){
return s;
}
//回文开始坐标
int start=0;
//回文的长度
int length=1;
int k=s.length();
//用一个二维数组,每个值都是记录下字符串各个位置是否为回文的情况
boolean[][] dp=new boolean[k][k];
//遍历数组
for(int i=0;i<k;i++){
for(int j=0;j<=i;j++){
//记录当前位置字符串是否为回文的情况
//两端的字符相等&&(间距小于3,或这个子串里面也是回文)
dp[i][j]= s.charAt(i)==s.charAt(j) && (i-j<3 || dp[i-1][j+1]);
//如果长度增加,记录下
if(dp[i][j] && length < i-j+1){
start=j;
length=i-j+1;
}
}
}
//返回结果
return s.substring(start,start+length);
}
}
运行结果: Runtime: 228 ms, faster than 32.58% of Java online submissions for Longest Palindromic Substring.
Memory Usage: 46.5 MB, less than 29.14% of Java online submissions for Longest Palindromic Substring.
解法二:双下标法
class Solution {
public String longestPalindrome(String s) {
if(s.length() < 2){
return s;
}
int sLength=s.length()-1;
int start=0;
int length=1;
Character pre=null;
//遍历字符串,从第二个值开始处理
for(int i=1;i<s.length();i++){
//相邻重复值只处理一次
if(pre != null && pre==s.charAt(i)){
continue;
}
pre=s.charAt(i);
//计算下相邻重复值,从当前位置,往两侧扩散
int left=i;
int right=i;
//往左判断,处理和当前位置值相同的数据
while(left > 0 && s.charAt(left-1)==pre){
left--;
}
//往右判断,处理和当前位置值相同的数据
while(right < sLength && s.charAt(right+1)==pre ){
right++;
}
//计算回文数,判断左右两侧的数值是不是相等
//注意边界条件
while(left > 0 && right < sLength && s.charAt(left-1)==s.charAt(right+1))
{
left--;
right++;
}
//计算下本次回文的长度
int l=right-left+1;
if(l > length){
start = left;
length=l;
}
}
//返回
return s.substring(start,start+length);
}
}
运行结果: Runtime: 14 ms, faster than 97.05% of Java online submissions for Longest Palindromic Substring.
Memory Usage: 43.2 MB, less than 35.53% of Java online submissions for Longest Palindromic Substring.