leetcode Longgest Palindrome Substring

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.

三种思路,一种是dp,一种是逐个延伸对称检测,还有一种比较高级的Manacher算法.

首先dp,这个我觉得是除了暴力解法之外比较容易想到的一种,我们另开一个boolean类型的二维数组,记录从i到j是否为回文数组,这样当我们在进行长度+2的判断的时候就不需要重新计算一遍,只需要计算i-1和j+1处索引的字符是否相等就可以了,代码:

public String longestPalindrome1(String s) {
    int len=s.length();
    if(len==0) return "";
    int max=1;
    int beginindex=0;
    int endindex=0;
    boolean[][] isPalindrome=new boolean[len][len];
    for(int i=0;i<len;i++)
        isPalindrome[i][i]=true;
    for(int i=0;i<len-1;i++){
        if(s.charAt(i)==s.charAt(i+1)) {
            isPalindrome[i][i + 1] = true;
            beginindex=i;
            endindex=i+1;
        }
    }
    for(int length=3;length<=len;length++){
        for(int i=0;i+length-1<len;i++){
            if(s.charAt(i)==s.charAt(i+length-1)&&isPalindrome[i+1][i+length-2]){
                    endindex=i+length-1;
                    beginindex=i;
                    isPalindrome[i][i+length-1]=true;
            }

        }
    }
    return s.substring(beginindex,endindex+1);
}
dp的时间复杂度和空间复杂度都是O(n^2)

第二种方法是时间复杂度O(n^2),空间复杂度O(1)的算法,算法本身思想很简单,从长度为n的字符串的2n-1个点出发向两侧延伸,取其中长度最长的字符串,为什么是2n-1呢,举个例子很容易明白 abba 我们分别需要从a ab之间 b bb之间 b ba之间 a这七个点进行延伸,代码:

public String longestPalindrome(String s) {
    int len=s.length();
    if(len<=1) return s;
    int maxlength=0;
    String maxstring="";
    for(int i=0;i<len-1;i++){
        String s1=getMaxString(s,i,i);
        if(s1.length()>maxlength){
            maxlength=s1.length();
            maxstring=s1;
        }
        String s2=getMaxString(s,i,i+1);
        if(s2.length()>maxlength){
            maxlength=s2.length();
            maxstring=s2;
        }
    }
    return maxstring;
}
public String getMaxString(String s,int begin,int end){
    int len=s.length();
    while(begin>=0&&end<len&&s.charAt(begin)==s.charAt(end)){
        begin--;
        end++;
    }
    return s.substring(begin+1,end);
}
第三个算法解释起来较为复杂,http://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html博主解释的非常清晰,建议大家有兴趣一定要看一看,这道题作为面试题的频率比较高,如果能拿出这个算法装个逼感觉还是挺爽的~我这里就贴下代码:

public String longestPalindrome(String s) {
        String temp="";
        for(int i=0;i<s.length();i++){
            temp=temp+"#"+s.charAt(i);
        }
        temp+="#";
        int[] length=new int[temp.length()];
        int C=0,R=0;
        for(int i=1;i<temp.length();i++){
            int mir=2*C-i;
            int dif=R-i;
            if(dif>=0){
                if(length[mir]<dif) length[i]=length[mir];
                else{
                    length[i]=dif;
                    while(i+length[i]+1<length.length&&i-length[i]-1>=0&&temp.charAt(i+length[i]+1)==temp.charAt(i-length[i]-1)){
                        length[i]++;
                    }
                    C=i;
                    R=i+length[i];
                }
            }
            else{
                length[i]=0;
                while(i+length[i]+1<length.length&&i-length[i]-1>=0&&temp.charAt(i+length[i]+1)==temp.charAt(i-length[i]-1)){
                    length[i]++;
                }
                R=i+length[i];
                C=i;
            }
        }
        int max=-1,index=0;
        for(int i=0;i<length.length;i++){
            if(length[i]>max){
                max=length[i];
                index=i;
            }
        }
        return s.substring((index-max)/2,(index+max)/2);


    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值