您的位置:首页 > 编程语言 > Java开发

leetcode-5-最长回文子串(longest palindromic substring)-java

2018-11-06 17:06 831 查看
版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/83787304

题目及测试

[code]package pid005;
/*最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

*/
public class main {

public static void main(String[] args) {
String[] testTable = {"babad","cbbd","ccc","eabcb"};
for (int i=0;i<testTable.length;i++) {
test(testTable[i]);
}
}

private static void test(String ito) {
Solution solution = new Solution();
String rtn;
long begin = System.currentTimeMillis();
System.out.println("ito="+ito);
rtn = solution.longestPalindrome(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn="+rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}

}

解法1(成功,138ms,很慢)
对0到length-1进行循环(不能循环到中间,因为字符串后半段也有可能有会文字符串)
对每个index,进行奇数会文和偶数会文的判断,奇数是两边相等,偶数是自身与右边相等
记录max的length和substring

[code]package pid005;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

public class Solution {
public String longestPalindrome(String s) {
int length=s.length();
if(length<=1){
return s;
}
int maxLength=0;
String maxString="";
for(int i=0;i<length;i++){//4 2(1)  5 3(2)
//首先检查以自己为中心(奇数会文)
int j=1;
int nowlength=1;
while(i-j>=0&&i+j<length){
if(s.charAt(i-j)==s.charAt(i+j)){
j++;
nowlength=nowlength+2;
}
else{
break;
}
}
if(nowlength>maxLength){
maxString=s.substring(i-(int)Math.floor(nowlength/2), i+(int)Math.floor(nowlength/2)+1);
maxLength=nowlength;
}
//检查偶数会文
j=0;
nowlength=0;
while(i-j>=0&&i+j+1<length){
if(s.charAt(i-j)==s.charAt(i+j+1)){
j++;
nowlength=nowlength+2;
}
else{
break;
}
}
if(nowlength>maxLength){
maxLength=nowlength;
maxString=s.substring(i-nowlength/2+1, i+nowlength/2+1);
}

}

return maxString;
}

}

解法2(别人的)

动态规划:

(一般含“最XX”等优化词义的题意味着都可以动态规划求解),时间复杂度O(n^2),空间复杂度O(n^2)。
 形如"abba", "abbba"这样的字符串,如果用dp[i][j]表示从下标i到j之间的子字符串所构成的回文子串的长度,则有:
 dp[i][j] = dp[i+1][j-1] && s[i] == s[j]
初始化:
 奇数个字符:dp[i][i] = 1; 偶数个字符:dp[i][i+1] = 1
若长度相同,返回最后一个子串
 

[code]public String longestPalindrome(String s) {
if (s == null || s.length() <= 1)
return s;
int n = s.length();
char[] cs = s.toCharArray();
int max = 1;
int maxIndex = 0;
boolean dp[][] = new boolean

;
// 初始化一个字母
for (int i = 0; i < n; i++) {
dp[i][i] = true;
maxIndex = i;
}
// 初始化两个相同的字母"aa"
for (int i = 0; i < n - 1; i++)
if (cs[i] == cs[i + 1]) {
dp[i][i + 1] = true;
// 返回最后一为2的子串
max = 2;
maxIndex = i;
}
// 从长度3开始操作, (aba)ba, a(bab)a, ab(aba)
for (int len = 3; len <= n; len++)
for (int i = 0; i < n - len + 1; i++) {
// j为从i~i + len - 1下标,长度为len
int j = i + len - 1;
// 字符相同,并且内部长度是回文
if (cs[i] == cs[j] && dp[i + 1][j - 1]) {
max = len;
// 因为长度递增,如果之后的的能进入这里都是比之前长的,
// 所以不需要判断大小
maxIndex = i;
dp[i][j] = true;
}
}
return s.substring(maxIndex, maxIndex + max);
}

解法3(别人的)

使用manacher算法

https://www.cnblogs.com/z360/p/6375514.html

http://blog.sina.com.cn/s/blog_70811e1a01014esn.html

 

 

 

 

 

 

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: