ltx_zero

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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);
    }
};
View Code

 额外试了一下,如果是前面直接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;
    }
};
内存占用大,没什么意义

 

posted on 2019-11-24 23:42  ltx_zero  阅读(112)  评论(0编辑  收藏  举报