10.3字符串manacher算法

字符串manacher算法

Manacher算法是用于在O(n)时间复杂度内查找字符串中最长回文子串的高效算法。以下是详细的技术解析:

一、算法核心思想

  1. 中心扩展优化:利用回文的对称性避免重复计算
  2. 奇偶统一处理:通过插入特殊字符将奇偶长度回文统一处理
  3. 动态维护边界:记录当前已知最右回文边界及其对应的中心

二、关键数据结构

vector<int> radius; // 存储每个位置的回文半径
int center = 0;     // 当前中心点
int right = 0;       // 当前最右边界

三、算法步骤详解

  1. 预处理字符串(示例:原字符串"abba"):

    string preProcess(string s) {
        string res = "^#";
        for(char c : s) {
            res += c;
            res += '#';
        }
        res += "$";
        return res;
    }
    // 转换后:"^#a#b#b#a#$"
    
  2. 主算法流程

string longestPalindrome(string s) {
    string T = preProcess(s);
    int n = T.size();
    vector<int> P(n, 0);
    int C = 0, R = 0;
  
    for(int i = 1; i < n-1; ++i) {
        // 计算镜像位置
        int mirror = 2*C - i;
      
        // 当i在R范围内时,利用对称性快速初始化
        if(i < R) {
            P[i] = min(R - i, P[mirror]);
        }
      
        // 中心扩展
        while(T[i + (1 + P[i])] == T[i - (1 + P[i])]) {
            P[i]++;
        }
      
        // 更新最右边界和中心
        if(i + P[i] > R) {
            C = i;
            R = i + P[i];
        }
    }
  
    // 找出最大回文子串
    int maxLen = 0;
    int centerIndex = 0;
    for(int i = 1; i < n-1; ++i) {
        if(P[i] > maxLen) {
            maxLen = P[i];
            centerIndex = i;
        }
    }
  
    // 计算原字符串中的起始位置
    int start = (centerIndex - maxLen)/2;
    return s.substr(start, maxLen);
}

四、关键点解析

  1. 镜像位置计算

    • 镜像位置公式:mirror = 2*C - i
    • 当i < R时,P[i]至少有min(R-i, P[mirror])
  2. 时间复杂度证明

    • 外层循环O(n)
    • 内层while循环总次数不超过n次(R单调递增)
    • 总体时间复杂度O(n)
  3. 回文半径计算

    • 最终最长回文长度 = max(P[i])
    • 原字符串中的起始位置 = (centerIndex - maxLen)/2

五、示例演算(输入"abba")

处理后的字符串:^ # a # b # b # a # $
对应的P数组:
[0,0,1,0,1,4,1,0,1,0,0]

最大值P[5] = 4,对应原字符串:
start = (5-4)/2 = 0
length = 4 → “abba”

六、算法优势

  1. 相比暴力解法O(n³)和动态规划O(n²),实现线性时间复杂度
  2. 空间复杂度O(n),仅需存储半径数组
  3. 巧妙处理奇偶长度回文问题
  4. 实际运行效率极高,适用于处理百万级长度的字符串

七、典型应用场景

  1. DNA序列分析
  2. 大规模文本处理
  3. 数据压缩
  4. 密码学中的模式匹配
  5. 社交网络中的敏感词检测

理解Manacher算法的关键在于掌握其利用回文对称性避免重复计算的策略,以及通过预处理统一处理奇偶长度的巧妙设计。该算法体现了计算机科学中空间换时间和利用已知信息优化计算的思想。10.3

你可能感兴趣的:(c++数据结构与算法,算法,c++)