defmanacher(s): # 预处理字符串 T = '^#' + '#'.join(s) + '#$' n = len(T) P = [0] * n # 回文半径数组 C, R = 0, 0# 回文中心和回文右边界 # 计算回文半径 for i inrange(1, n - 1): i_mirror = 2 * C - i # 计算i关于C的对称点 if R > i: # 如果i在回文右边界R的左侧,则i的回文半径至少为i到R的距离 P[i] = min(R - i, P[i_mirror]) else: # 如果i在回文右边界R的右侧,则i的回文半径至少为0 P[i] = 0 # 尝试扩展回文串 while T[i + P[i] + 1] == T[i - P[i] - 1]: P[i] += 1 # 更新回文中心和回文右边界,如果i的回文半径大于R,则更新回文中心和回文右边界,保证回文中心和回文右边界是当前最大的 if i + P[i] > R: C = i R = i + P[i]
classSolution { private: vector<string> path; vector<vector<string>> ans; vector<int> p; public: voidmancher(string s){ string t = "$#"; for(char& c : s) { t += c; t += '#'; } int n = t.size(); p.resize(n, 0); int c = 0; int r = 0; for(int i=1; i<n; i++) { if(i<r) { p[i] = min(p[2*c-i], r-i); } else { p[i] = 1; } // 扩展左右边界 while(i-p[i]>=0 && i+p[i] <n && t[i-p[i]] == t[i+p[i]]) { p[i]++; } // 更新右边界 if(i+p[i] > r) { c = i; r = i+p[i]; } } }
// 判断当前子串是不是回文子串 boolisPalindrome(string& s, int left, int right){ // 左闭右闭 int center = left+right+2; // 映射到预处理字符串的中心 int len = right - left + 1; // 子串长度 return p[center] >= len+1; // 只有当前中心点的回文半径大于等于当前子串的长度,才能算回文子串 }