标签:子串 位置 stp 字符 题目 length lse mil 中心
题目:输出最长回文子串,原串最长1000
坑:特判s="";
复习一下马拉车算法,之前写的只求答案,没有要输出子串。
class Solution { public String longestPalindrome(String s) { //特判s="" if(s.length()==0) return s; char[] a=new char[20005]; int [] p=new int[20005];//记录每个位置的半径 a[0]=‘!‘;//首尾加上不相干字符 int cnt=1;//a的下标计数 for(int i=0;i<s.length();i++){ a[cnt]=‘#‘; cnt++; a[cnt]=s.charAt(i); cnt++; } a[cnt]=‘#‘; cnt++; a[cnt]=‘@‘;//首尾加上不相干字符 /* 预处理结束,算法开始 i:表示当前遍历到哪一个下标的字符 p[idx]:表示下标为idx的字符的回文半径,包括自身 id:目前遍历过程中能延展到最右的回文的中心点 mx:目前遍历过程中能延展到最右的下标位置,姑且称之为探测的最远长度 j:以id为中心的关于i对称的字符,在id的左边,已经遍历过了,p[j]已经确定了的 ans:最长回文子串的长度 t:最长回文子串在原串的起始下标 */ int ans=2; int t=0; int id=1,mx=1; int len=2*s.length()+3;//插#加首尾后的长度 for(int i=1;i<len;i++) { int j=2*id-i; if(mx>i) { if(mx-i>=p[j]) p[i]=p[j];//i和j以id对称,但以id为中心的字符串包括了以i或j为中心的的最长回文子串 else p[i]=mx-i; }else p[i]=1; //暂定了p[i],还是有可能更大,中心扩展 while( a[ i+p[i] ]==a[ i-p[i] ] ) p[i]++; if(i+p[i]>mx) {//更新最右点和对应的id id=i; mx=id+p[i]; } if(p[i]>ans) {//更新答案 ans=p[i]; t=(id-p[id])/2;//记录最长回文子串在原串的起始下标 } } ans--;//去掉#作为对称边缘带来的影响 return s.substring(t,t+ans); } }
标签:子串 位置 stp 字符 题目 length lse mil 中心
原文地址:https://www.cnblogs.com/shoulinniao/p/12331147.html