Longest Palindromic 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.

样例:

S="acbbcc"

return "cbbc"

首先考虑的果然还是枚举的办法,没什么技术含量,O(n^2)的时间复杂度,直接贴代码了:

#include <string.h>
char* longestPalindrome(char* s) {
    int i,j,k1,k2,i_tmp,len,max[2]={0,0};
    len=strlen(s);
    for(i=0;i<len-1;i++){
        j=i-1;
        i_tmp=i+1;
        while(s[i_tmp]==s[i_tmp-1]){
            i_tmp++;
            if(i_tmp>len-1)
                break;
        }
        while(s[j]==s[i_tmp]&&i_tmp<=len-1&&j>=0){
            j--;
            i_tmp++;
        }
        i_tmp--,j++;
        if(i_tmp-j>max[1]-max[0]){
            max[0]=j;
            max[1]=i_tmp;
        }
    }
    char *answer=malloc((max[1]-max[0]+2)*sizeof(char));
    for(k1=0,k2=max[0];k2<=max[1];k2++)
        answer[k1++]=s[k2];
    answer[k1]=‘\0‘;
    return answer;
}

击败52%的C提交,看起来提升空间应该蛮大的。因为官方带Editorial Solution,所以我就偷个懒,直接看看还有哪些解法了。

第一个解法也是O(n^2)的算法。颠倒字符串S得到字符串S1,寻找S和S1的最长公共子串,如果公共子串的下标值相同,它就是我们要找的最长回文子串,如果不是,我们跳过它接着寻找。思路不难理解,但寻找两个字符串的最长公共子串也挺麻烦的,这里我就不用这种算法了。

之后看到一个巧妙的O(n)算法,其实就是我上面写的算法的改进。我写的算法对于每一个元素都朝元素两边扩张来计算以它为中心的回文字串的大小,也就是说从元素本身,从一开始扩张。而这个O(n)算法的思想是利用回文字符串的对称性减少一些不必要的计算,说白了也就是说不从元素本身开始扩张。而是利用回文字符串的对称性,利用之前已经计算过的元素的回文字串大小来避免从一开始扩张的情况。具体可以看看下面这篇博客:

https://www.felix021.com/blog/read.php?2040

下面贴一下我根据这个思路改进的代码(顺便修改了一些原来没写好的地方)

char* longestPalindrome(char* s) {
    int i,j,i_tmp,max[2]={0,0},p[1100],mid_l=0,mid_r=0,maxP=0;
    for(i=0;i<1100;i++)
        p[i]=0;
    for(i=0;s[i+1]!=‘\0‘;i++){
        j=i-1;
        while(s[i]==s[i+1])
            i++;
        i_tmp=i+1;
        if(i<mid_r+maxP&&i+p[mid_l-(i-mid_r)]<=mid_r+maxP){
            j-=p[mid_l-(i-mid_r)];
            i_tmp+=p[mid_l-(i-mid_r)];
        }
        while(s[j]==s[i_tmp]&&i_tmp!=‘\0‘&&j>=0){
            j--;
            i_tmp++;
        }
        i_tmp--,j++;
        p[i]=i_tmp-i;
        if(i_tmp-j>max[1]-max[0]){
            max[0]=j;
            max[1]=i_tmp;
            mid_r=i;
            for(i_tmp=i;i_tmp==i_tmp-1;i_tmp--)
                ;
            mid_l=i_tmp;
            maxP=mid_l-j;
        }
    }
    char *answer=malloc((max[1]-max[0]+2)*sizeof(char));
    for(i=0,j=max[0];j<=max[1];j++)
        answer[i++]=s[j];
    answer[i]=‘\0‘;
    return answer;
}

之所以是p[1100]而不是p[1000]是因为我用p[1000]的时候竟然说我runtime error了,不知道leetcode搞什么鬼,于是加了100。

注意我的算法是把连续的元素当作一个整体处理的,所以我分了mid_l和mid_r。

运行时间达到了惊人的0ms..(-_-),击败了99%的C提交,看来这一波很强势,好的,那今天就到这收工。

时间: 2024-10-12 16:53:19

Longest Palindromic Substring问题的相关文章

[string]Longest Palindromic Substring

Total Accepted: 82026 Total Submissions: 379898 Difficulty: Medium 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. Subscrib

LeetCode OJ:Longest Palindromic 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. 玩了两天dota2,罪过罪过,还是应该老老实实刷题啊. 题目求得是最长的回文子串,这里使用的是暴力的解法,也就是解决两种回文"asdsa"以

5. Longest Palindromic Substring - Unsolved

https://leetcode.com/problems/longest-palindromic-substring/#/description Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example: Input: "babad" Output: "bab" Note: &

[Leetcode] Longest palindromic 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. 做这道题之前要先了解什么是回文子串.回文串通俗的解释是,分别从字符串两端开始遍历,得到的结果相同,如"abba",从两端的遍历结果都是:&q

【leedcode】 Longest Palindromic 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. https://leetcode.com/problems/longest-palindromic-substring/ 求最大回文的长度,其实这道题

5. Longest Palindromic 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. 思路:(beat 2.63%) 以一个位置为准,考察两侧相同距离是否相同.这样会导致"aaaaaaaaaaaaaaaaaaaaaaaaaa...&qu

LeetCode #5 Longest Palindromic Substring (M)

[Problem] 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. [Analysis] 这题的思路有很多种,网上也有各种讨论.这里我采用的是个人觉得比较好理解的一种利用Dynamic Progra

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之余全部耗在这上面了,只怪自己基础差.本文主要介绍使用Manacher线性算法来求解字符串的最长回文子字符串. 题目 Given a string S, find the longest palindromic substring in S. You may assume that the maxim

[C++]LeetCode: 99 Longest Palindromic 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. 思路:题目要求的s的一个最长回文子串.暴力解决办法就是枚举所有的子串,再对每个子串进行回文判断.进行剪枝,我们考虑可以使用动态规划来避免重复的判

[译]最长回文子串(Longest Palindromic Substring) Part II

[译+改]最长回文子串(Longest Palindromic Substring) Part II 问题:给定字符串S,求S中的最长回文子串. 在上一篇,我们给出了4种算法,其中包括一个O(N2)时间O(1)空间的算法(中心检测法),已经很不错了.本篇将讨论一个O(N)时间O(N)空间的算法,即著名的Manacher算法,并详细说明其时间复杂度为何是O(N). 提示 +BIT祝威+悄悄在此留下版了个权的信息说: 先想想有什么办法能改进中心检测法. 考虑一下最坏的情况.★ 最坏的情况就是各个回文