美文网首页C++互联网科技程序员
四种方法求最长回文串

四种方法求最长回文串

作者: 海天一树X | 来源:发表于2018-03-03 19:13 被阅读82次

所谓回文串,就是正着读和倒着读结果都一样的回文字符串。
比如:
a, aba, abccba都是回文串,
ab, abb, abca都不是回文串。

一、暴力法

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

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

#include <iostream>
using namespace std;

string longestPalindrome(string &s)
{
    int len = s.size();                  //字符串长度
    int maxlen = 1;                      //最长回文字符串长度
    int start = 0;                       //最长回文字符串起始地址
    for(int i = 0; i < len; i++)         //起始地址
    {
        for(int j = i + 1; j < len; j++) //结束地址
        {
            int tmp1 = i, tmp2 = j;
            while(tmp1 < tmp2 && s.at(tmp1) == s.at(tmp2))//判断是不是回文
            {
                tmp1++;
                tmp2--;
            }

            if(tmp1 >= tmp2 && j - i + 1 > maxlen)
            {
                maxlen = j - i + 1;
                start = i;
            }
        }
    }

    return s.substr(start, maxlen);
}

int main()
{
    string s;
    cout << "Input source string: ";
    cin >> s;
    cout << "The longest palindrome: " << longestPalindrome(s);
    return 0;
}

运行结果:

Input source string: abbacdeedc
The longest palindrome: cdeedc

二、动态规划

设状态dp[j][i]表示索引j到索引i的子串是否是回文串。则转移方程为:

1.png

则dp[j][i]为true时表示索引j到索引i形成的子串为回文子串,且子串起点索引为j,长度为i - j + 1。
算法时间复杂度为O(N ^ 2)。

#include <iostream>
#include <cstring>
using namespace std;

string longestPalindrome(string s)
{
    const int n = s.size();
    bool dp[n][n];
    memset(dp, 0, sizeof(dp));

    int maxlen = 1;     //保存最长回文子串长度
    int start = 0;      //保存最长回文子串起点
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j <= i; ++j)
        {
            if(i - j < 2)
            {
                dp[j][i] = (s[i] == s[j]);
            }
            else
            {
                dp[j][i] = (s[i] == s[j] && dp[j + 1][i - 1]);
            }

            if(dp[j][i] && maxlen < i - j + 1)
            {
                maxlen = i - j + 1;
                start = j;
            }
        }
    }

    return s.substr(start, maxlen);
}

int main()
{
    string s;
    cout << "Input source string: ";
    cin >> s;
    cout << "The longest palindrome: " << longestPalindrome(s);
    return 0;
}

三、中心扩展法

中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,这样来找最长的子回文串。算法复杂度为O(N^2)。
需要考虑两种情况:
长度为奇数的回文串,比如a, aba, abcba
长度为偶数的回文串,比如aa, abba

#include <iostream>
#include <cstring>
using namespace std;

string longestPalindrome(string &s)
{
    const int len = s.size();
    int maxlen = 1;
    int start = 0;

    for(int i = 0; i < len; i++)//求长度为奇数的回文串
    {
        int j = i - 1, k = i + 1;
        while(j >= 0 && k < len && s.at(j) == s.at(k))
        {
            if(k - j + 1 > maxlen)
            {
                maxlen = k - j + 1;
                start = j;
            }

            j--;
            k++;
        }
    }

    for(int i = 0; i < len; i++)//求长度为偶数的回文串
    {
        int j = i, k = i + 1;
        while(j >= 0 && k < len && s.at(j) == s.at(k))
        {
            if(k - j + 1 > maxlen)
            {
                maxlen = k - j + 1;
                start = j;
            }

            j--;
            k++;
        }
    }

    return s.substr(start, maxlen);
}


int main()
{
    string s;
    cout << "Input source string: ";
    cin >> s;
    cout << "The longest palindrome: " << longestPalindrome(s);
    return 0;
}

四、Manacher算法

Manacher算法的时间复杂度为O(N),具体可参考:
https://www.cnblogs.com/grandyang/p/4475985.html



更多内容请关注微信公众号


feicuisenlin_12x12.jpg

相关文章

  • Manacher's Algorithm算法分析Java

    Manacher's Algorithm俗称马拉车算法,对于求字符串中最长回文子串效率极高。 在求最长回文子串的时...

  • LeetCode 第647题:回文子串

    1、前言 2、思路 此题与最长回文子串很像,只不过那个是求最长的回文子串,而这个是求回文子串的数目。但是他们的解法...

  • 最长回文子串

    最长回文子串——Manacher 算法 1. 问题定义 最长回文字符串问题:给定一个字符串,求它的最长回文子串长度...

  • 四种方法求最长回文串

    所谓回文串,就是正着读和倒着读结果都一样的回文字符串。比如:a, aba, abccba都是回文串,ab, abb...

  • 最长回文子串问题—Manacher算法

    最长回文串问题是一个经典的算法题。 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度。如果...

  • LeetCode 5. 最长回文子串(Longest Palin

    5. 最长回文子串 切题 一、Clarification 求最长回文子串,这里有几个特殊情况需要考虑1、空字符串,...

  • 字符串---Manacher

    求最长回文子串 求一个串中的回文子串,首先将字符串处理成奇数个。如"abbc"处理成Ma = "$ a # b #...

  • 最长回文子串

    问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度。 解法1:暴力解法 找到字符串的所有子串,判断...

  • 字符串

    最长回文子串 1. 题目 已知一个只包含大小写的字符串,求用该字符串可以生成的最长回文子串的长度。 2. 思路 首...

  • 字符串最长回文子串

    字符串最长回文子串 题目描述: 给定一个字符串,求它的最长回文子串的长度。 分析和解法: 最容易想到的办法是枚举所...

网友评论

    本文标题:四种方法求最长回文串

    本文链接:https://www.haomeiwen.com/subject/eqkxfftx.html