欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

最长回文子串(含manacher算法)

程序员文章站 2022-07-13 21:53:01
...

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

解答:

法一:先找到两两配对的,例如bab,bb这样的形式,再扩展
class Solution {
public:
    string tostr(char c){
        string s;
        stringstream ss;
        ss<<c;
        ss>>s;
        return s;
    }
    
    string longestPalindrome(string s) {
        vector<int> vec;
        int i,max=0;
        string rs="";
        
        if(s.length()==1)
            return s;
        
		//寻找两两配对
        for(i=0;i<s.length()-2;i++){
            if(s[i]==s[i+2] && s[i]==s[i+1])
            {
                vec.push_back(i);
                i+=2;
            }
            else if(s[i]==s[i+2])
                vec.push_back(i);
            else if(s[i]==s[i+1])
                vec.push_back(i);
		}
        if(i<s.length()-1 && s[i]==s[i+1])
			vec.push_back(i);

        //遍历vec,扩展取最大长度串 
        int distance;
        string sstr;
        for(int j=0;j<vec.size();j++){
        	int pos=vec[j],d=0;
			distance=0;sstr="";
        	if(s[pos]==s[pos+2])
        	{
        		sstr=tostr(s[pos])+tostr(s[pos+1])+tostr(s[pos+2]);
				d=pos+3;
				distance=3;
        	}
			else
        	{
        		sstr=tostr(s[pos])+tostr(s[pos+1]);
				d=pos+2;
				distance=2;
        	}
        	for(int k=pos-1;k>0;k--){
        		if(s[k]==s[d])
        		{
        			sstr=tostr(s[k])+sstr+tostr(s[d]);
					distance++;
        		}
				else
        			break;
			}
			
			//更新最长回文串
			if(max<distance) 
			{
				max=distance;
				rs=sstr;
			}
		}
		return rs;
    }
};

法二:manacher算法
class Solution {
public:
    string longestPalindrome(string s) {
        char str[s.size()*2+10];
        int n=0;
        //填充#使奇偶性一致
        str[n++]='#';
        for(int i=0;i<s.size();i++){
            str[n++]=s[i];
            str[n++]='#';
        }
        str[n]='\0';
        
        int p[n+1],mx=0,pos=0;            //mx为最右,pos为对称轴
        memset(p,1,sizeof(p));
        //遍历求p数组
        for(int i=1;i<n;i++){
            //重点步骤!
            if(i<mx)
                p[i]=min(p[2*pos-i],mx-i);
            else
                p[i]=1;
            
            //扩充
            while(i >= p[i] && str[i+p[i]]==str[i-p[i]]){
                   p[i]++;
            }
            
            //更新mx和pos
            if(i+p[i] > mx){
                mx = i+p[i];
                pos = i;
            }
        }
        
        //求最长回文串
        mx=p[1];pos=1;
        for(int i=1;i<n;i++)
        {
            if(p[i] > mx){
                mx=p[i];
                pos=i;
            }
        }
        mx-=1;
        string r="";
        for(int i=pos-mx+1;i<pos+mx;i+=2)
           r.push_back(str[i]);
        
        return r;
    }
};
最长回文子串(含manacher算法)