字符串算法manacher算法

来源:互联网 发布:mac软件下载安装 编辑:程序博客网 时间:2024/04/30 21:00

manacher是一种线性时间复杂度算法,对于给定的字符串s, 可以在O(n)时间内,求出以每个位置为中心的最长回文子串。

  1. 插入无关字符
    在相邻字符之间以及字符串首尾分别插入s中没出现的字符,设为#,得到str。则str中以任意位置为中心的最长回文串长度是奇数。

  2. p[i]=max{j|str(ij...i+j)}

    因此只要求出p数组即可。
  3. 假设从左向右扫描,当前在i点,定义

    id=argmaxj{j+p[j] | j<i}

    分两种情况:
    1. i < id + p[id], 这时找 i关于id的对称点id*2-i,根据该点p值更新i点;
    2. i >= id + p[id], 暴力求解i点p值

  4. 因为每次比较都是在增加id+p[id]的值,显然id+p[id]上限是字符串长度,因此复杂度O(n)。

class Solution {public:    string longestPalindrome(string s) {        char st[s.length()*2+5] = {0};        int p[s.length()*2+5] = {0};        int len = 0;        st[len++] = '%';        for (int i = 0; i < s.length(); ++i) {            st[len++] = '#', st[len++] = s[i];        }        st[len++] = '#'; st[len] = '\0';        p[0] = 0;        int ans = 0;        for (int id = 0, i = 1; i < len - 1; ++i) {            int r = id + p[id];            p[i]= r > i ? min(p[id * 2 - i], r - i) : 1;            while(st[i - p[i]] == st[i + p[i]]) ++ p[i];            if (i + p[i] > r) id = i;            if (p[i] > p[ans]) ans = i;         }        return s.substr((ans - p[ans])/2, p[ans]-1);    }};
0 0
原创粉丝点击