LEECODE 5 求最长回文子串

212 阅读2分钟

闲来无事,刷题玩耍~

题目如下: 求最长回文子串

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

大意就是给你一个字符串,求其中最长的回文字串,最大长度1000.

王老菊说遇事不决莽一波 第一次上的算法是暴力求解,时间复杂度n^3,不出所料的超时了~

以下是AC的算法:

根据回文串的特点,在中轴两侧对应位置的字符应当相等。

将一个位置pos作为中轴,遍历两侧的字符,直到不相等或超出范围为止,即可求得以此pos为中轴的最长回文串。

以上情况仅适用于回文串的字符为奇数时,存在中轴字符。当回文串的字符数为偶数时,将pos和pos+1同时作为中轴,向两侧扩展遍历即可。

算法的时间复杂度为o(n^2),提交AC

代码如下,详见注释:

package leecode;

/**
 * 最长回文字串
 * Created by shizhida on 16/4/21.
 */
public class P5_Longest_Palindromic {

    /**
     * 求最长回文字串
     * @param str
     * @return
     */
    public static String longestPalindromic(String str){

        int maxlength = 0;
        int lpos = 0,rpos = 0;

        for(int i=0;i<str.length();i++){
            //假设为奇
            int len1 = searchAround(str,i,0);
            //假设为偶
            int len2 = searchAround(str,i,1);
            if(len1>maxlength)
            {
                maxlength = len1;
                lpos = i-len1/2;
                rpos = i+len1/2+1;
            }
            if(len2>maxlength)
            {
                maxlength = len2;
                lpos = i-len2/2+1;
                rpos = i+len2/2+1;
            }

        }
        System.out.println(maxlength);
        return str.substring(lpos,rpos);

//        return maxlength;
    }

    /**
     * 从中心点开始校验左右
     * @param str
     * @param pos
     * @param sub
     * @return
     */
    public static int searchAround(String str,int pos,int sub){

        int l = 0,//左侧延伸
                r = 0+sub,//右侧延伸
                length=0;//最终长度

        while(pos-l>=0&&pos+r<str.length()&&//超出范围
                str.charAt(pos-l)==str.charAt(pos+r)//两侧不等
                ){
            length = r+l;//长度为左+右+差值
            //同步扩大范围
            l++;
            r++;

        }
        return length+1;//会漏掉中间一个(奇)或少算旁边一个(偶),所以都要+1
    }

}