Longest Palindromic Substring 算法总结

Longest Palindromic Substring 即寻找一个字符串的最长回文子串,这个问题是leetcode上面的一个题目,刚开始自己做的时候用了一个可能是效率最低的方法去实现,但是由于leetcode的代码提交时会评价代码的执行效率,因此,这种实现没能通过。仔细看一下代码的时间复杂度几乎是O(n³),所以慢是很自然的。下面是这个算法的实现:

string longestPalindrome(string s) 
{
    int size = s.size();
    if (size == 1)
    {
        return s;
    }

    string resultString;
    for (int i = 0; i < size; ++i)
    {
        for (int j = i + 1; j < size; ++j)
        {
            int left = i;
            int right = j;
            bool ok = true;
            while (left <= right)
            {
                if (s[left] != s[right])
                {
                    ok = false;
                    break;
                }

                ++left;
                --right;
            }
            if (ok)
            {
                string newSubstr = s.substr(i, j-i+1);
                if (newSubstr.size() > resultString.size())
                {
                    resultString = newSubstr;
                }
            }
        }
    }
    if(resultString.size() == 0)
    {
        return s.substr(0, 1);
    }

    return resultString;

}

后来去网上看到另外一种实现Manacher算法,这个算法的时间复杂度是O(n)相率已经相当高了。

string longestPalindrome(string s)
{
    string T("#");
    for (int i = 0; i < s.size(); ++i)
    {
        T.append(1, s[i]);
        T.append("#");
    }
    int Tsize = T.size();
    T = "@" + T + "\0";

    vector<int> Len(T.size(), 1);

    int Po = 1;
    int p = 1;
    int maxindex = 1;
    for (int i = 1; i < Tsize; ++i)
    {
        if (i < p)
        {
            Len[i] = min(Len[2 * Po - i], p - i);
        }
        while (T[i - Len[i]] == T[Len[i] + i])
        {
            Len[i]++;
        }
        if (i + Len[i] > p)
        {
            p = i + Len[i];
            Po = i;
        }

        maxindex = Len[i] > Len[maxindex] ? i : maxindex;
    }

    int length = Len[maxindex] - 1;
    int start = (maxindex - Len[maxindex]) / 2;
    return s.substr(start, length);

}

参考:
http://blog.csdn.net/hk2291976/article/details/51107886
http://blog.csdn.net/hk2291976/article/details/51108655

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值