目录
最长回文子串
描述
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串 A 以及它的长度 n,请返回最长回文子串的长度。
示例1
输入:
扫描二维码关注公众号,回复: 13161603 查看本文章"abc1234321ab",12
返回值:
7
方法一:动态规划
我们用数组 dp[left][right] 来表示位于 left 和 right 之间的字符串是否为回文子串,那么我们就很容易得到递推关系式,
dp[left][right] = dp[left+1][right-1] && A.charAt(left)==A.charAt(right),
import java.util.*;
public class Solution {
public int getLongestPalindrome(String A, int n) {
// write code here
if(n==0||n==1) return n;
boolean dp[][]=new boolean[n][n];
int maxLen=0;
for (int right = 1; right < n; right++) {
for (int left = 0; left < right; left++) {
//若左右两个字符不同,则dp[left][right]一定为false
if(A.charAt(left)!=A.charAt(right)) continue;
//若左右两个字符相同,还要进一步判断
//1.如果right-left<3(可取0,1,2),那么我们认为是回文字串,dp[left][right]=true
//2.如果right-left>=3,需要根据dp[left+1][right-1]的真假来判断dp[left][right]
if (right-left<3){
dp[left][right]=true;
}else{
dp[left][right]=dp[left+1][right-1];
}
//保留最长的回文字串长度
if (dp[left][right]==true){
maxLen=maxLen>right-left+1?maxLen:right-left+1;
}
}
}
return maxLen;
}
}
方法二:中心扩散法
import java.util.*;
public class Solution {
public int getLongestPalindrome(String A, int n) {
// write code here
int maxLen=1;
for (int i = 0; i < n; i++) {
if (n-i<=maxLen/2) break;
int left=i-1,right=i+1;
if(left>=0&&right<n){
while (A.charAt(left)==A.charAt(i) && left-1>=0){
left=left-1;
}
while (A.charAt(right)==A.charAt(i) && right+1<n){
right=right+1;
}
while (A.charAt(left)==A.charAt(right)){
maxLen=maxLen>right-left+1?maxLen:right-left+1;
left=left-1;
right=right+1;
if (left<0 || right>=n) break;
}
}
}
return maxLen;
}
}
该方法比动态规划时间消耗和空间消耗都要小得多,
方法三:暴力搜索
暴力搜索就是遍历所有的字串,然后判断是否是回文串,返回最大长度即可,
import java.util.*;
public class Solution {
public int getLongestPalindrome(String A, int n) {
// write code here
if (n < 2)
return n;
int maxLen = 0;
for (int i = 0; i < n - 1; i++) {
for (int j = i; j < n; j++) {
//截取所有子串,如果截取的子串小于等于之前遍历过的最大回文串,直接跳过
if (j - i < maxLen)
continue;
if (isPalindrome(A, i, j)) {
if (maxLen < j - i + 1) {
maxLen = j - i + 1;
}
}
}
}
return maxLen;
}
//判断是否是回文串
private boolean isPalindrome(String s, int start, int end) {
while (start < end) {
if (s.charAt(start++) != s.charAt(end--))
return false;
}
return true;
}
}
时间消耗最慢,