[Happy DSA] 求解最長迴文子字符串

題目:輸入一個字符串,輸出該字符串中對稱的子字符串的最大長度。

比如輸入字符串google,由於該字符串裏最長的對稱子字符串是goog,因此輸出4


關於這個問題,有一個比較好的線性時間複雜度的算法Manacher's ALGORITHM

這2篇技術博客非常好的闡述了它的算法思想:

1) http://www.felix021.com/blog/read.php?2040 (中文)

2) http://www.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html


更多的博客文章可供參考:

http://www.akalin.cx/longest-palindrome-linear-time


C++代碼實現:

// longest palindromic substring
// http://www.felix021.com/blog/read.php?2040
// Manacher's ALGORITHM: O(n)
std::string lps(const std::string& str)
{
    std::cout << "original string is " << str << std::endl;
    std::string ss = "$";
    std::ostringstream ostr;
    for (int i = 0; i < str.length(); i++)
    {   
        ostr << '#' << str[i];
    }   
    ostr << "#";
    ss += ostr.str();
    std::cout << "new string is " << ss << std::endl;

    int* p = new int[ss.length()];
    *p = 0;

    int id = 0, mix = 0;
    for (int i = 1; i < ss.length(); i++)
    {   
        p[i] = (mix > i) ? std::min(p[2*id - i], mix-i) : 1;
        while (ss[i + p[i]] == ss[i-p[i]]) p[i]++;
        if (p[i] + i > mix)    
        {   
            mix = p[i] + i;
            id = i;
        }   
    }   
    
    int* pmax = std::max_element(p, p+ss.length());
    int ipos = (pmax - p)/2;
    int len = *pmax - 1;
   std::string lpsstr = str.substr(ipos-len/2, len);

    delete [] p;
    return lpsstr;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章