最长回文子串
题目:给你一个字符串 s,求出 s 中最长回文子串。
**方法1:**首先想到的解题思路是暴力解法,即遍历给出的字符串,直接罗列所有子串,判断是否为回文,是则记录该字符串及其长度……若又出现一个回文子串,且长度大于之前记录的子串长度,则修改记录回文串和长度的值。
public class MaxStr{
/*
* 方法1:暴力解法:罗列所有子串,检查其是否为回文及其长度
*/
public static void main(String[] args) {
String str = "abcdacbcaded";
String ans = "";
int max = 0;
//遍历字符串
for (int i = 0; i < str.length(); i++) {
for (int j = i+1; j <= str.length(); j++) {
String temp = str.substring(i, j);
if (isTrue(temp) && temp.length()>max) {
//是回文串并且,长度大于记录的max,则修改ans回文串,及最大值
ans = temp;
max = ans.length();
}
}
}
System.out.println("最长回文串为:"+ ans +",其长度为:"+max);//最长回文串为:dacbcad,其长度为:7
}
//定义方法判断子串是否为回文
public static boolean isTrue(String temp) {
int n = temp.length();
for (int i = 0; i < n/2; i++) {
if (temp.charAt(i)!= temp.charAt(n-1-i)) {
return false;
}
}
return true;
}
}
时间复杂度:O(n^3)
方法2:
同样罗列子串,但使用动态规划与方法1相比降低了时间复杂度。若(i + 1 ,j - 1)是回文串,则要想知道(i , j)是否为回文,只需要判断 i 处元素是否等于 j 处元素。
public class MaxStr{
/*
* 方法2:动态规划
*/
public static void main(String[] args) {
String str = "abcdacbcaded";
int n = s.length();
int max = 0;
String maxAns = "";
boolean[][] p = new boolean[n][n];
for(int len = 1; len <= n;len++){//遍历所有长度的子串
for(int start = 0;start < n;start++){
int end = start + len -1;//长度减1为结束索引
if(end >= n){//最大索引不可能等于长度
//越界,退出本次循环
break;
}
//判断是否为回文
p[start][end] = (len == 1 || len==2 || p[start+1][end-1])&&(s.charAt(start) == s.charAt(end));
if(p[start][end] && len > max){
maxAns = s.substring(start,end+1);
max = maxAns.length();
}
}
}
System.out.println("最长回文串为:"+ maxAns +",其长度为:"+max);//最长回文串为:dacbcad,其长度为:7
}
}
时间复杂度O(n^2)