Num 5 最长回文子串
Manacher是专门用于解决这个问题的算法
说明:
1、temp:在所有字符前面插入了#的新字符串,注意最头和最尾巴也插入,这样所有原来字符都在奇数位置
2、maxcenter:已知的最大的回文串中心位置
3、maxend:目前最大回文串覆盖的尾部索引号
4、在判断i的时候,如果他被包含在某个回文串里面,那么他与前面的某个字符附近的东西是对应的,相应的,如果那个字符串在对应部分有回文,那么他的这部分有回文
5、注意限制,如果超出了镜像的部分,是不是不确定,所以下限是min(边界-相同,镜像点的半径)。
几个在leetcode需要注意的地方(字符串堆栈溢出):
1、在插入#产生新的字符串的时候,使用push_back可以避免堆栈溢出(好像是如果给空可能附近有别的干扰,默认分配不够)
2、在后面判断的时候是用temp
3、最后返回的时候用substr返回,s.substr(start,len),第二个是截取长度
class Solution { public: string longestPalindrome(string s) { if(s=="") return ""; string temp="#"; for(int i=0;i<s.length();i++) { //temp[2*i+1]=s[i]; //temp[2*i+2]='#'; temp.push_back(s[i]); temp.push_back('#'); } int rec[3000]; memset(rec,0,sizeof(rec)); int maxend=0,maxcenter=0; for(int i=0;i<2*s.length()+1;i++) { if(maxend>i) { rec[i]=min(rec[2*maxcenter-i],maxend-i); } while(i-rec[i]>0 && i+rec[i]<2*s.length()+1-1 && temp[i-rec[i]-1]==temp[i+rec[i]+1]) rec[i]++; if(rec[i]>rec[maxcenter]) { maxend=i+rec[i]; maxcenter=i; } } int start,len; if(temp[maxcenter]=='#') { if(temp[maxend]=='#') { start=maxcenter-maxend/2; len=maxend-maxcenter; } else { start=maxcenter-(maxend+1)/2; len=maxend-maxcenter+1; } } else { if(temp[maxend]=='#') { start=maxcenter-maxend/2; len=(maxend-maxcenter)/2*2+1; } else { start=maxcenter-(maxend+1)/2; len=maxend-maxcenter; } } return s.substr(start,len); } };
额外试了一下,如果是前面直接string g然后存,最后返回g,这样不会溢出,但是没什么意义。。就是多占用了内存。(但是一个字符一个字符的肯定是不推荐奥。pushback没试,直接赋值肯定溢出)
class Solution { public: string longestPalindrome(string s) { if(s=="") return ""; string temp="#"; for(int i=0;i<s.length();i++) { temp.push_back(s[i]); temp.push_back('#'); } int rec[3000]; memset(rec,0,sizeof(rec)); int maxend=0,maxcenter=0; for(int i=0;i<2*s.length()+1;i++) { if(maxend>i) { rec[i]=min(rec[2*maxcenter-i],maxend-i); } while(i-rec[i]>0 && i+rec[i]<2*s.length()+1-1 && temp[i-rec[i]-1]==temp[i+rec[i]+1]) rec[i]++; if(rec[i]>rec[maxcenter]) { maxend=i+rec[i]; maxcenter=i; } } int start,len; string g; if(temp[maxcenter]=='#') { if(temp[maxend]=='#') g=s.substr(maxcenter-maxend/2,maxend-maxcenter); else g=s.substr(maxcenter-(maxend+1)/2,maxend-maxcenter+1); } else { if(temp[maxend]=='#') g=s.substr(maxcenter-maxend/2,(maxend-maxcenter)/2*2+1); else g=s.substr(maxcenter-(maxend+1)/2,maxend-maxcenter); } return g; } };