Suffix array:把所有后缀排好序
Trie 与 Aho-Corasick 预处理的是 pattern。换个极端:如果 text 固定不变、却要被反复查询各种 pattern(搜索引擎、基因组),那就值得花一次力气把 text 本身预处理好。关键观察:pattern 在 text 里出现,等价于 pattern 是 text 某个后缀的前缀。把 text 的全部后缀按字典序排好,所有以 pattern 开头的后缀必然集中在连续一段里——于是查询变成一次 binary search。
1 · 第一步:列出全部后缀并排序
长度为 n 的 text 有 n 个后缀。suffix array 就是「这些后缀按字典序排序后的起始下标数组」——只存下标,不真的存字符串。(教学实现直接排序;工程上用 SA-IS / 倍增可做到近线性。)
2 · 第二步:对 pattern 做 binary search
在排好序的后缀上二分:每次比 pattern 与 mid 那条后缀的开头。pattern 偏小往左半区,偏大往右半区,正好是某后缀的前缀(命中)就继续向左收边界,最终定位到「命中段」的左端。命中段里每条后缀的 start 下标,就是 pattern 在 text 中的一处出现。
查询代价:二分 O(log n) 轮,每轮最多比 pattern 长度 m 个字符 → O(m·log n),与 text 多长基本无关。同一个 suffix array 还能顺带支持「最长重复子串 / 不同子串计数」等问题,配合 LCP 数组更强。代价依旧是构建与存储那一次性开销。