看见题目,觉得哪种解法写起来都挺麻烦,所以先上一个暴力解法吧,判断回文数借助了题目palindrome-number中的思想,不过复杂度已经到 O(n^3)了,算法耗时也已经超过天际了,大概只超过了 3%的人吧。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | class Solution {public String longestPalindrome(String s) {
 char[] sc=s.toCharArray();
 if(sc.length<=1)
 return s;
 int longest=0;
 int left=0;
 int right=0;
 for(int i=0;i<sc.length;i++){
 for(int j=i+1;j<=sc.length;j++){
 boolean needUpdate=true;
 for(int m=i,n=j-1;m<=n;m++,n--){
 if(sc[m]!=sc[n]){
 needUpdate=false;
 break;
 }
 }
 if(needUpdate && j-i+1>longest){
 longest=j-i+1;
 left=i;
 right=j;
 }
 }
 }
 return s.substring(left,right);
 }
 }
 
 | 
sigh,又拖了一周。
接着,参考网上的动态规划的思路,可以建立一个数组,将以前的结果进行记录。之前判断过的串都可以被利用起来。
参考博客: https://www.cnblogs.com/grandyang/p/4464476.html
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | class Solution {public String longestPalindrome(String s) {
 char[] sc=s.toCharArray();
 if(sc.length<=1)
 return s;
 boolean[][] dp = new boolean[sc.length][sc.length];
 int longest=0;
 int left=0;
 int right=0;
 for(int i=0;i<sc.length;i++){
 dp[i][i]=true;
 for(int j=0;j<i;j++){
 if(sc[i]==sc[j] && (i-j<2 || dp[j+1][i-1])){
 dp[j][i]=true;
 if(i-j+1>longest){
 longest=i-j+1;
 left=j;
 right=i;
 }
 }
 }
 }
 return s.substring(left,right+1);
 }
 }
 
 | 
最后,是 Manacher’s Algorithm,也叫马拉车算法。使用这个算法使用空间换取时间,十分巧妙地将算法的时间复杂度降到 O(n)。
主要参考了https://blog.csdn.net/insistgogo/article/details/12287805和http://www.cnblogs.com/grandyang/p/4475985.html这两篇文章。
算法的主要地方在于构建回文串半径数组,只要它被填充完,最大回文串就能找到。而算法中方采取了一个关键方式来构建它:
| 1
 | p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
 | 
这个关键算法和最大回文串半径的长度有关。具体可以参考上面的两篇文档,文档搬运到此结束,我就不当稳当搬运工了。
这个方法的确很有意思,值得再去回味。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 | class Solution {public String longestPalindrome(String s) {
 char[] sc=s.toCharArray();
 StringBuilder sb=new StringBuilder("$#");
 for(int i=0;i<sc.length;i++){
 sb.append(sc[i]);
 sb.append('#');
 }
 char[] nsc=sb.toString().toCharArray();
 int[] p=new int[nsc.length];
 int id=0;
 int mx=0;
 int resLen=0;
 int resCenter=0;
 for(int i=0;i<nsc.length;i++){
 p[i] = mx>i ? Math.min(p[2*id-i], mx-i) : 1;
 while(i-p[i]>=0 && i+p[i]<nsc.length && nsc[i+p[i]]==nsc[i-p[i]]) p[i]++;
 if(mx<i+p[i]){
 mx=i+p[i];
 id=i;
 }
 if(resLen<p[i]){
 resLen=p[i];
 resCenter=i;
 }
 }
 return s.substring((resCenter-resLen)/2,(resCenter-resLen)/2+resLen-1);
 }
 }
 
 |