LeetCode------最长回文子串

https://leetcode-cn.com/problems/longest-palindromic-substring/

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

四种算法:

一、暴力法

双指针双重循环切分字符串,双指针查找对比。

时间复杂度O(n^3)

char* longestPalindrome(char* s) {
    int length = strlen(s),l =0,r = length-1,index1=0,index2=0,max = 0,n = 0,flag=1;
    char *p=NULL;
    if(length<=1) return s;
    for(int i = 0;imax){
                    max = n;
                    index1 = i;
                    index2 = j;
                }
            }
        }
    }
    p = (char*)malloc(sizeof(char)*(index2-index1+2));//复制回文串
    for(int i = index1;i<= index2;i++){
        p[i-index1] = s[i];
    }
    p[index2-index1+1]  ='\0';
    return p;
}//时间复杂度O(n^3)空间复杂度O(1)

二、中心拓展算法

n个字符串有2*n-1个回文中心,比如abbab,对于单个字符,中心是它本身,如a,对于双字符,中心是空,如bb。

只要从中心向两端匹配,就能匹配出当前回文串的长度。

int expand(char *s,int left,int right,int length);
char* longestPalindrome(char* s) {
    int length=strlen(s),l=0,r=0;
    char *p=NULL;
    for(int i = 0;i < length;i++){        //最基本的回文单位是单字符或者相同双字符。
        int len1 = expand(s,i,i,length);  //遍历所有单字符
        int len2 = expand(s,i,i+1,length); //遍历所有连续双字符
        int len = len1 > len2 ? len1 : len2;
        if(len > r - l){            //这句话等于(len>=r-l+1)而r-l+1为同样长的字符串
            l = i - (len-1)/2;      //根据中点值,计算左右界限
            r = i + len/2;
        }
    }
    p = (char *)malloc(r-l+2);    //复制数组
    for(int i = l;i<=r;i++){
        p[i-l]=s[i];
    }
    p[r-l+1] = '\0';
    return p;
}
int expand(char *s,int left,int right,int length){  //拓展函数,返回长度
    int l = left,r = right;
    while(l>=0 && r

三、动态规划

设置辅助数组dp[length][length],以若从起始点为i,结束点为j,且i,j范围内的字符串是回文,那么dp[i][j]=1。

边界条件,dp[i][i] = 1,dp[i][i+1] = dp[i] == dp[i+1].

状态转移方程:dp[i][j] = dp[i+1][j-1] && dp[i]==dp[j];

char* longestPalindrome(char* s) {
    int length = strlen(s),max = 0,index1=0,index2=0;
    char **p=NULL,*p1=NULL;
    p = (char **) malloc(sizeof(char*)*length);
    for(int i = 0;i

四、Manacher算法

请自行阅读相关文献

char* longestPalindrome(char* s) {
    int length = strlen(s),*len=NULL;
    int mid=1,mx=0,max_mid=0,max = 0;
    char *p=NULL,*p2=NULL;
    if(length==0) return s;
    p = (char *)malloc(length+length+3);
    p[0] = '$';
    p[1] = '#';
    for(int i=0,j=2;imx){      //若新的右界大于当前右界,则重置中点,重置右界
            mx = i+len[i];            
            mid = i;
        }
        if(len[i]>max){   //记录最长串中点和半径
            max = len[i];
            max_mid = i;
        }
    }
    p2 = (char *)malloc(max+2);  //将回文串复制到新的数组。
    for(int i = max_mid - max +2,j=0;i<=max_mid+max-2;i++){
        if(p[i]=='#') continue;
        else{
            p2[j++] = p[i];
        }
        if(i==max_mid+max-2) p2[j]='\0';
    }
    return p2;          //返回
}//时间复杂度O(n) 空间复杂度O(n)

 

你可能感兴趣的:(LeetCode)