• 算法题之最大回文子串


    题目描述
    对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
    给定字符串A以及它的长度n,请返回最长回文子串的长度。

    测试样例:
    "abc1234321ab",12

    返回:7

    1. 普通轮询(运行时间80ms):

    class Palindrome {
    public:
        bool isHuiWen(string A, int n){
            int k = n / 2;
            for (int i = 0; i < k; ++i)
            {
                if (A.at(i) != A.at(n - 1 - i))
                    return false;
            }
            return true;
        }
    
        int getLongestPalindrome(string A, int n) {
            // write code here
            int maxlen = 0;
            for (int i = 0; i< n; i++){
                for (int j = i + 1; j <= n; j++){
                    //两层循环遍历出所有的子串,并且逐一判断是否是回文
                    if (isHuiWen(A.substr(i, j-i), j - i)){
                        if (j - i>maxlen)
                            maxlen = j - i;
                    }
                }
            }
            return maxlen;
        }
    };
    

    附:Leetcode上一个不错的递归解法:

    #include <iostream>
    
    using namespace std;
    
    int lps(char* str, int i, int j)
    {
        //只有一个元素,长度为1
        if (i == j)
            return 1;
        //只计算序列str[i...j]
        if (i > j)
            return 0;
    
        //如果首尾相同
        if (str[i] == str[j])
            return lps(str, i+1, j-1) + 2;
        //如果首尾不同
        return max(lps(str, i, j-1), lps(str, i+1, j));
    }
    
    
    int main()
    {
        char* str = "AABACACBA";
        cout << lps(str, 0, strlen(str)-1) << endl;
        return 0;
    }

    2. 动态规划(运行时间40ms):

    import java.util.*;
     
    public class Palindrome {
        public int getLongestPalindrome(String A, int n) {
            // write code here
            int[][] dp = new int[n][n];
            int max = 1;
            for (int i = 0; i < n; ++i) {
                dp[i][i] = 1;
            }
            char[] a = A.toCharArray();
            for (int len = 2; len <= n; ++len) {
                for (int i = 0; i <= n - len; ++i) {
                    int j = i + len - 1;
                    if (len == 2 && a[i] == a[j]) {
                        dp[i][j] = len;
                        max = 2;
                        continue;
                    }
                    if (a[i] == a[j] && dp[i + 1][j - 1] != 0) {
                        dp[i][j] = len;
                        max = len;
                    }
                }
            }
            return max;
        }
    }
    

    另一种解法:

    //动态规划求解最长回文子序列,时间复杂度为O(n^2)  
    int lpsDp(char *str, int n)  
    {  
        int dp[n+1][n+1], tmp;  
        memset(dp, 0, sizeof(dp));  
        for (int i = 0; i < n; ++i)  dp[i][i] = 1;  
    
        for (int i = 1; i < n; ++i)  
        {  
            tmp = 0;  
            //考虑所有连续的长度为i+1的子串,str[j....j+i]  
            for (int j = 0; j + i < n; j++)  
            {  
                //如果首尾相同  
                if (str[j] == str[j + i])  
                    tmp = dp[j + 1][j + i - 1] + 2;  
                //如果首尾不同  
                else   
                    tmp = max(dp[j + 1][j + i], dp[j][j + i - 1]);  
                dp[j][j + i] = tmp;  
            }  
        }  
        return dp[0][n - 1]; //返回字符串str[0...n-1]的最长回文子序列长度  }

      

    3. Manacher解法(时间复杂度O(n),运行时间<1ms):

    class Palindrome {
    public:
        int getLongestPalindrome(string A, int n) {
             
            int max = 1;
            for (int i = 0; i < n; i++)
            {
                int num = 1;
                for (int left = i - 1, right = i + 1; left >= 0 && right < n; left--, right++)
                {
                    if (A[left] == A[right])
                    {
                        num += 2;
                    }
                    else
                    {
                        break;
                    }
                }
                if (max < num)
                {
                    max = num;
                }
             
            }
            for (int i = 0; i < n; i++)
            {
                int num = 0;
                for (int left = i, right = i + 1; left >= 0 && right < n; left--, right++)
                {
                    if (A[left] == A[right])
                    {
                        num += 2;
                    }
                    else
                    {
                        break;
                    }
                }
                if (max < num)
                {
                    max = num;
                }
            }
            return max;
             
        }
    };
    

      

  • 相关阅读:
    转:调试Release发布版程序的Crash错误
    [原创]桓泽学音频编解码(9):MP3 多相滤波器组算法分析
    [转] 一些你不知道但是超美的地方,一定要去
    [原创]桓泽学音频编解码(11):AC3 exponent(指数部分)模块解码算法分析
    [原创]桓泽学音频编解码(14):AC3 时频转换模块算法分析
    [原创]桓泽学音频编解码(15):AC3 最终章 多声道处理模块算法分析
    Android Supported Media Formats
    VoiceChatter 编译记录
    [原创]桓泽学音频编解码(4):MP3 和 AAC 中反量化原理,优化设计与参考代码中实现
    OPUS 视频PPT介绍
  • 原文地址:https://www.cnblogs.com/shixiangwan/p/6740309.html
Copyright © 2020-2023  润新知