最长回文串 时间复杂度n求解(马拉车算法代码)

今天在leetcode上刷回文子串时发现了这个算法,是实现回文串寻找的时间复杂度为n的算法。

之前刷一些博客讲解真的不知所谓,越看越晕,但其实算法很简单,就是个从头到尾求len数组的过程

在这里推荐这篇博客,是在这篇博客看懂这个算法的(https://blog.csdn.net/dyx404514/article/details/42061017

需要注意的细节是加#号和在标号0位置加$的原因。

接下来贴代码:

public static String longestPalindrome(String s) {
            //char数组存放扩增后的string字符串
	        char p[]=new char [2*s.length()+3];
            p[0]='$';p[1]='#';
	        p[2*s.length()+2]='\0';

            //sum[i]即以i为中心的最大子串的半径
            int sum[]=new int[2*s.length()+3];
            sum[0]=1;sum[1]=1;
            
            //填充数组
	        for(int i=1;i<=s.length();i++) {
	        	p[2*i]=s.charAt(i-1);
	        	p[2*i+1]='#';
	        	
	        }
            
            //max存放当前最大回文半径,maxindex存放最大半径对应的中心
	        int max=-1;int maxindex=-1;

            //求扩充后数组以i为中心的各个回文串长度,记录在sum[i]中
	        for(int i=2;i<2*s.length()+3;i++) {
	        	int tem=-2;
                //i大于当前最大位置
	        	if(i>=max)
	        		{sum[i]=getsum(p, i);tem=sum[i];}
	        	else {
                //小于时
	        		if(sum[2*maxindex-i]+i-1<=max)
	        			sum[i]=sum[2*maxindex-i];
	        		else
	        			{sum[i]=getsum(p, i);tem=sum[i];}
	        	}
	        	if(tem>max) {
	        		max=tem;maxindex=i;
	        	}
	        }
	       System.out.println(maxindex);
	       System.out.println(max);
	    
	    	   int len=(max-1);
	    	   int j=0;
	    	   char returnarr[]=new char [len];
	    	   for(int i=maxindex-max+2;i<maxindex+max-1;i=i+2,j++)
	    		   returnarr[j]=p[i];
	    	   return String.valueOf(returnarr);
	      
	    }

        //求以i为中心的最长回文
	    public static int getsum(char p[],int i){
	        int sum=1;int a=i-1;int b=i+1;
	        while(a>=0&&b<p.length){
	            if(p[a]==p[b])
	            {sum++;a--;b++;}
	            else
	                break;
	        }
	        return sum;
	    }

猜你喜欢

转载自blog.csdn.net/Ms_huang_/article/details/84984809
今日推荐