最长回文子串----leetcode每日一练

第一次:

void checkstr(char* x, int y, int z, int* start, int* max)
{
    int i = y, j = z;
    int length = 0;
    while(i>=0 && j<= strlen(x)-1 && (x[i] == x[j]))
    {
        i--;
        j++;
    }
    length = j-i-1;
    if(length > *max)
    {
        *max = length;
        *start = i+1;
    }   
}

char* longestPalindrome(char* s) {
    int begin = 0, max = 1;
   // int L = strlen(s);
    if(strlen(s)<=1)
    {
        return s;
    }
    if(strlen(s)>1000)
    {
        return NULL;
    }
    for(int i=0; i<strlen(s)-1; i++)
    {
        //奇字符串
        checkstr(s, i, i, &begin, &max);
        //偶数
        checkstr(s, i, i+1, &begin, &max);
    }
    char* result = (char*)malloc(sizeof(char)*(max+1));
    memcpy(result, &s[begin], sizeof(char)*max);
    result[max] = '\0';
    return result;
}

以上时间会超过,在上面基础上优化后时间可以接受,优化方式是,不需要每次都计算s字符串的大小

void checkstr(char* x, int y, int z, int* start, int* max, int l)
{
    int i = y, j = z;
    int length = 0;
    while(i>=0 && j<= l-1 && (x[i] == x[j]))
    {
        i--;
        j++;
    }
    length = j-i-1;
    if(length > *max)
    {
        *max = length;
        *start = i+1;
    }   
}

char* longestPalindrome(char* s) {
    int begin = 0, max = 1;
    int L = strlen(s);
    if(L<=1)
    {
        return s;
    }
    if(L>1000)
    {
        return NULL;
    }
    for(int i=0; i<strlen(s)-1; i++)
    {
        //奇字符串
        checkstr(s, i, i, &begin, &max, L);
        //偶数
        checkstr(s, i, i+1, &begin, &max, L);
    }
    char* result = (char*)malloc(sizeof(char)*(max+1));
    memcpy(result, &s[begin], sizeof(char)*max);
    result[max] = '\0';
    return result;
}

上述用到的方法是以一个点为中心,分为偶数字符串和奇数字符串两种情况,分别向左右两边扩展,寻找回文;时间复杂度是(O(n^2)).  另外可以根据   

i+max/2 <strlen(s)进行再次优化


下面再介绍

马拉车算法 Manacher Algorithm计算最长回文长度

int longestPalindrome(char* s)
{
    int length = strlen(s);
    char p[2*length+2];
    int L[2*length+1];
    char* result;
    int i=0,j=0;
    int po=1,p_max=2,ans=2;
    for(i=0; i<length; i++)
    {
        p[2*i] = '#';
        p[2*i+1] = s[i];
    }
    p[2*length]='#';
    p[2*length+1]='\0';
    memset(&L,0,sizeof(int)*(2*length+1));
    L[0]=0;
    L[1]=2;
    for(j=2;j<=2*length;j++)
    {
        if(j<p_max)
        {
            L[j] = p_max-j+1<L[2*po-j]?p_max-j+1:L[2*po-j];
        }
        else
        {
            L[j] = 1;
        }
        while((j-L[j]+1>=0)&&(j+L[j]-1<=2*length)&&(p[j-L[j]+1]==p[j+L[j]-1]))
        {
            L[j]++;
        }
        if(L[j]>p_max-po+1)//若新计算的回文串右端点位置大于mx,要更新po和mx的值  
         {  
             p_max=L[j]+j-1;  
             po=j;  
         }  
         ans=ans>L[j]? ans:L[j];
    }
    return ans-1;
}



根据提供的引用内容,有三种方法可以解决LeetCode上的最长回文子串问题。 方法一是使用扩展中心法优化,即从左向右遍历字符串,找到连续相同字符组成的子串作为扩展中心,然后从该中心向左右扩展,找到最长的回文子串。这个方法的时间复杂度为O(n²)。\[1\] 方法二是直接循环字符串,判断子串是否是回文子串,然后得到最长回文子串。这个方法的时间复杂度为O(n³),效率较低。\[2\] 方法三是双层for循环遍历所有子串可能,然后再对比是否反向和正向是一样的。这个方法的时间复杂度也为O(n³),效率较低。\[3\] 综上所述,方法一是解决LeetCode最长回文子串问题的最优解法。 #### 引用[.reference_title] - *1* [LeetCode_5_最长回文子串](https://blog.csdn.net/qq_38975553/article/details/109222153)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Leetcode-最长回文子串](https://blog.csdn.net/duffon_ze/article/details/86691293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [LeetCode 第5题:最长回文子串(Python3解法)](https://blog.csdn.net/weixin_43490422/article/details/126479629)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值