zoukankan      html  css  js  c++  java
  • LeetCode 5 最长回文子串 Manacher线性算法

    题目链接:https://oj.leetcode.com/problems/longest-palindromic-substring/


    回文串即正向反向序列都一样的连续序列 如abba,abcba...

    为了统一回文串的偶数情况和奇数情况,可以向串中插入不相关的字符,例如abba->#a#b#b#a#, abcba->#a#b#c#b#a#


    建立数组arr[]记录主串中以第i个字符为中心的回文串向右延伸的长度(即向右覆盖长度,不包括s[i])

    例如:

    第一种情况:


    设变量mx为当前向右最大覆盖位置下标,id为该回文串对称中心下标。在例子中,达到最右覆盖位置的为index=5,覆盖到5+arr[5]=8.所以,此时,mx=8,id=5

    在计算arr[7]时(图中‘?’处i=7),可以利用arr[0~6]的值,发现7位于以id为对称中心的覆盖范围内(图中黄色部分)。并且,i=7的对称位置id*2-i=3的覆盖范围(蓝色部分)并未超出id的覆盖范围(黄色部分),所以,arr[7]可直接利用arr[3]的值,令arr[7]=arr[3].


    另外一种情况:i未超出黄色部分,但蓝色不服超出了黄色部分。如下图:

    此时,arr[7]的值至少为其关于id=5的对称位置:arr[3].所以,先为arr[7]赋初值=arr[3].然后,再从(i+arr[i]+1),(i-arr[i]-1)分别向两端遍历即可。


    最后一种情况,即i超出了黄色部分(i>=mx),这时,只能为arr[i]赋初值arr[i]=0,并向两端遍历


    代码:

    class Solution
    {
    public:
    	string longestPalindrome(string s)
    	{
    		string tem;
    		for(int i=0;i<s.length();i++)
    		{
    			tem.push_back('#');
    			tem.push_back(s[i]);
    		}
    		tem.push_back('#');
    		s=tem;
    		tem.clear();
    
    		int *arr=new int[s.length()+5];		//以i为中心最长串向右延伸长度
    		memset(arr,0,sizeof(arr));
    		int id=0;							//对称中心
    		int mx=0;							//右边界
    		int maxid=0;						//最长回文中心
    		for(int i=1;i<s.length();i++)
    		{
    			if(i>=mx)						//在范围外
    				arr[i]=0;
    			else							//在范围内
    			{
    				if(arr[id*2-i]<arr[id]+id-i)
    				{
    					arr[i]=arr[id*2-i];
    					continue;
    				}
    				else
    					arr[i]=mx-i;			//肯定>or=该值
    			}
    			while(s[i-arr[i]-1]==s[i+arr[i]+1]&&i-arr[i]-1>=0&&i+arr[i]+1<s.length())
    				arr[i]++;
    
    			if(i+arr[i]>mx)					//更新延伸最右位置
    			{
    				id=i;
    				mx=id+arr[id];
    			}
    			if(arr[i]>arr[maxid])				//更新最长串中心
    				maxid=i;
    
    		}
    		for(int i=maxid-arr[maxid];i<=maxid+arr[maxid];i++)
    		{
    			if(s[i]=='#')
    				continue;
    			else
    				tem.push_back(s[i]);
    		}	
    		return tem;
    
    	}
    
    };


  • 相关阅读:
    Mac安装WineHQ
    Ubuntu 16.04下使用Wine安装文件比对工具Beyond Compare 4
    Ubuntu 16.04下安装WineHQ
    Ubuntu 16.04下使用Wine安装PowerDesigner15
    Ubuntu 16.04下使用Wine安装Windows版的微信(不太完美)
    Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4
    MySQL中数据类型(char(n)、varchar(n)、nchar(n)、nvarchar(n)的区别)(转)
    Ubuntu 16.04安装MongoDB的GUI工具RoboMongo
    Linux下Shell的快捷键(转)
    Jackson反序列化错误:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field的解决方法
  • 原文地址:https://www.cnblogs.com/frankM/p/4399434.html
Copyright © 2011-2022 走看看