• Algorithm --> 最长回文子串


    1、中心扩展

    中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串。算法复杂度为O(N^2)

    但是要考虑两种情况:

    1、像aba,这样长度为奇数。

    2、想abba,这样长度为偶数。
    代码如下:
    string findLongestPalindrome(string &s)
    {
        const int length=s.size();
        int maxlength=0;
        int start;
    
        for(int i=0;i<length;i++)//长度为奇数
        {
            int j=i-1,k=i+1;
            while(j>=0&&k<length&&s.at(j)==s.at(k))
            {
                if(k-j+1>maxlength)
                {
                    maxlength=k-j+1;
                    start=j;
                }
                j--;
                k++;
            }
        }
    
        for(int i=0;i<length;i++)//长度为偶数
        {
            int j=i,k=i+1;
            while(j>=0&&k<length&&s.at(j)==s.at(k))
            {
                if(k-j+1>maxlength)
                {
                    maxlength=k-j+1;
                    start=j;
                }
                j--;
                k++;
            }
        }
        if(maxlength>0)
            return s.substr(start,maxlength);
        return NULL;
    }
     
     
     
    2、动态规划
     
    有母串s,我们用c[i, j] = 1表示子串s[i..j]为回文子串,空间和算法复杂度也是O(N^2)。那么就有递推式:
    c[i,j]={ c[i+1,j−1],   if s[i]=s[j]
                   0if s[i]≠s[j]

    递推式表示在s[i] = s[j]情况下,如果s[i+1..j-1]是回文子串,则s[i..j]也是回文子串;如果s[i+1..j-1]不是回文子串,则s[i..j]也不是回文子串。

    初始状态:

        c[i][i] = 1
        c[i][i+1] = 1 if s[i] == s[i+1]

    上述式子表示单个字符、两个字符均是回文串[j]

    int longestPald(char *str) {
        int len = strlen(str);
        int c[maxLen][maxLen];
        int i,j;
        int longest = 1;
        
        assert(str != NULL);
        if(len == 1) {
            return 1;
        }
          //initialization
        for(i = 0; i < len; i++) {
            c[i][i] = 1;
            if(str[i] == str[i+1])
               c[i][i+1] = 1;
        }
    
        for(i = 0; i < len; i++) {
            for(j = i+2; j <= len; j++) {
                if(str[i] == str[j]) {
                    c[i][j] = c[i+1][j-1];
                    //find longest palindrome substring
                    if(c[i][j]) { 
                        int n = j - i + 1;
                        if(longest < n)
                            longest = n;                
                    }
                } else {
                    c[i][j] = 0;
                }
            }
        }
        return longest;
    }

    3、暴力法

    最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个。

    求每一个子串时间复杂度O(N^2),判断子串是不是回文O(N),两者是相乘关系,所以时间复杂度为O(N^3)。

    string findLongestPalindrome(string &s)
    {
        int length=s.size();//字符串长度
        int maxlength=0;//最长回文字符串长度
        int start;//最长回文字符串起始地址
    for(int i=0;i<length;i++)//起始地址 for(int j=i+1;j<length;j++)//结束地址 { int tmp1,tmp2; for(tmp1=i,tmp2=j;tmp1<tmp2;tmp1++,tmp2--)//判断是不是回文 { if(s.at(tmp1)!=s.at(tmp2)) break; } if(tmp1>=tmp2&&j-i>maxlength) { maxlength=j-i+1; start=i; } } if(maxlength>0) return s.substr(start,maxlength);//求子串 return NULL; }

    4、Manacher法(待续)

  • 相关阅读:
    Github markdown页面内跳转
    github gist 无法访问
    Install pyaudio on Ubuntu
    删除链表的倒数第N个节点
    电话号码的字母组合
    最长公共前缀
    盛最多水的容器
    字符串转化整数与回文数
    Z 字形变换
    LeetCode1-5题
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4564809.html
Copyright © 2020-2023  润新知