方法一:动态规划
定义P(i,j):如果字符串从i位置到j位置是回文,P(i,j)=true;否则,P(i,j)=false;
那么P(i,j)= P(i+1,j−1) && Si==Sj
首先初始化一字母和二字母的回文:
P(i,i)=true P(i, i) = true P(i,i)=true
P(i,i+1)=(Si==Si+1)
然后找到所有三字母回文,并依此类推…
复杂度分析
-
时间复杂度:O(n2)
-
空间复杂度:O(n2), 该方法使用 O(n2) 的空间来存储表。
public String longestPalindrome(String s) {
if(s == null || s.length() <= 1){
return s;
}
int len = s.length();
//flag[i][j]=true 表示子串i-j为回文字符串
boolean[][] flags = new boolean[1000][1000];
int start = 0;
int maxlen = 0;
for(int i=0; i<len; i++){
flags[i][i] = true;
if(maxlen==0||maxlen==1){
start = i;
maxlen = 1;
}
//相邻的两个字符相同
if( i<len-1 && s.charAt(i) == s.charAt(i+1)){
flags[i][i+1] = true;
start = i;
maxlen = 2;
}
}
//m代表回文子串长度,从3开始
for(int m = 3; m <= len; m++){
for(int i = 0; i <= len-m; i++ ){
//依次比较是否符合状态转移方程
int j = i+m-1;
if(flags[i+1][j-1] && s.charAt(i)==s.charAt(j)){
flags[i][j] = true;
start = i;
maxlen = m;
}
}
}
return s.substring(start, start+maxlen);
}
方法二:中心扩展算法
事实上,只需使用恒定的空间,我们就可以在 O(n2)的时间内解决这个问题。
回文中心的两侧互为镜像。因此,回文可以从它的中心展开
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
int L = left, R = right;
while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
L--;
R++;
}
return R - L - 1;
}
(方法三思路有错,不能求解回文串,如字符串:"aacdecaa",输出为acc)
方法三可以用来求字符串逆序序列和原序列中最长的公共字符串
方法三
得到字符串的逆序字符串,将当前字符串的子串和逆序字符串对比,看逆序字符串是否包含子串,并且当长度大于之前最长回文串时,更新最长回文串为当前子串
public static String getLongestSymmetryString(String s){
String reverseString = new StringBuffer(s).reverse().toString();
String res="";
int max = 0;
int start, end;
for(int i=0; i<s.length(); i++){
start = i;
for(end = s.length(); ; end--){
if(start >=end) break;
String substr = s.substring(start, end);
int temp = end - start;
if(temp>max && reverseString.contains(substr)) {
res=substr;
max = temp;
}
}
}
return res;
}