LeetCode 5 最长回文子串 manacher算法

时间:2019-02-17
本文章向大家介绍LeetCode 5 最长回文子串 manacher算法,主要包括LeetCode 5 最长回文子串 manacher算法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:

https://leetcode-cn.com/problems/longest-palindromic-substring/

题意:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

思路:

直接用manachermanacher算法,复杂度O(n)O(n)。另外还有一种很迷的算法,有时候会比manachermanacher算法跑的还快,自行体会。

代码:

manacher算法

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.size() == 0)
            return s;

        string cs(2*s.size() + 2, '#');
        for(int i = 0; i < s.size(); i++) {
            //cs[2*i] = '#';
            cs[2*i+2] = s[i];
        }
        cs[0] = '?';

        int k = 0, extk = 0, index = 0;
        vector<int> p(2*s.size() + 2, 0);
        for(int i = 2; i < cs.size(); ++i) {
            if(i < extk) {
                p[i] = min(extk-i, p[2*k-i]);
            } else {
                p[i] = 1;
            }

            while(i + p[i] < cs.size() && cs[i+p[i]] == cs[i-p[i]])
                p[i]++;
            if(i + p[i] > extk) {
                k = i, extk = i + p[i];
                if(p[i] > p[index])
                    index = i;
            }
        }
        return s.substr((index-p[index]+2)/2-1, p[index]-1);
    }
};

迷之算法

class Solution {
public:
    string longestPalindrome(string s) {
        int index = 0, ans = 0;
        for(int i = 0; i < s.size(); i++) {
            int l = i, r = i;
            while(r+1 < s.size() && s[r+1] == s[i])
                r++;
            while(l-1 >= 0 && r+1 < s.size() && s[l-1] == s[r+1])
                l--, r++;
            if(r - l + 1 > ans) {
                index = l;
                ans = r - l + 1;
            }
        }
        return s.substr(index, ans);
    }
};