回文就是顺序和逆序一样的字符串。
试了两种方法

1.中心扩展算法

一个长度为n的字符串,中心个数为2n-1
leetcode--最长回文子串
扩展方式:
当中心点左右的字符相同,就扩展回文的边界left和right(left–,right++),直到左右边界的字符不相同。这样就得到了从这一中心点能扩展到的最长的回文子串。

从头到位遍历所有中心点,记录最长的回文子串~解决问题

代码:

char* longestPalindrome(char* s) {
    int len = strlen(s);
    if(len <= 1)
        return s;    
    int start = 0,end = 0;
    for(int i = 0; i < len; i++)
    {
        int len1 = expandlist(s,i,i);  
        int len2 = expandlist(s,i,i+1);
        int maxlen = max(len1,len2);
        if(maxlen > end-start+1)    //更新回文子串
        {
            start = i - (maxlen - 1)/2;
            end = i + maxlen/2;
        }
    }
    char *r=(char*)malloc(sizeof(int)* ((end-start+2)));   //动态申请数组
    strncpy(r,s+start,end-start+1);   
    r[end-start+1] = '\0';  
    return r;
}

int expandlist(char* s, int i, int j)   //获取最长回文子串长度函数
{
    int len = strlen(s);
    int left = i,right = j;
    while(left>=0&&right<len&&s[left]==s[right]) 
    {
        left--;
        right++;
    }
    return right-left-1;
}
int max(int a, int b)
{
    return a>b?a:b;
}

2.动态规划

创建一个二维数组a[][],a[i][j]用来记录第i个字符到第j个字符的子串是否为回文。
逻辑:
j-i=0,单个字符,肯定是回文
j-i=1,两个字符,如果两个字符相同则是回文
j-i>1,多个字符,如果第i个和第j个字符相同 && 第i+1个字符到第j-1个字符形成的子串是回文,则是回文

代码:

char* longestPalindrome(char* s) {
    int len = strlen(s);
    if(len <= 1)
        return s;  
    int **a;   //用二级指针动态申请二维数组 
    a=(int**)malloc(sizeof(int*)*len);  
    for(int i=0;i<len;i++)
        a[i]=(int*)malloc(sizeof(int)*len);  
    int left = 0;
    int right = 0;
    for(int i=len-2;i>=0;i--)
    {
        a[i][i] = 1;
        for(int j = i+1;j<len;j++)
        {
            if(s[i]==s[j]&&(j-i<3||a[i+1][j-1]==1))  
            {
                a[i][j]=1;
            }
           if(j-i>right-left && a[i][j] == 1)    
           {
               left = i;
               right = j;
           }
        }
    }
    char *r=(char*)malloc(sizeof(int)* ((right-left+2)));
    strncpy(r,s+left,right-left+1);
    r[right-left+1] = '\0';
    return r;
}


相关文章: