今天,我们来介绍一下解决字符串问题的一大利器——后缀数组。
几个定义
为了下文表示的方便,我们需要先达成几个共识。
1、字符串的位置从0开始标号,一直到n-1.
2、后缀i,表示从i...n-1这些字符按顺序组成的字符串。显然,该字符串是原字符串的一个后缀。
3、字符串的大小比较:从第0个位置开始比较。如果相同,继续往后比;如果不同,则当前位置字符ASCII码大的对应字符串更大。如果仍无法比较大小,则长度长的字符串更大,否则两者相等。举个栗子:
后缀数组是啥
后缀数组,顾名思义,就是把一个字符串的每一个后缀都进行排序。在这个算法中,我们需要处理得到两个数组,第一个数组记录的排名第i的后缀是哪一个(sa数组),第二个数组是第i个后缀的排名是多少。
举个栗子:
sa数组就是我们通常所说的后缀数组,而rank数组可以通过sa数组快速求得。我们这个算法就是为了快速地求出sa数组的值。
后缀数组怎么求
求解后缀数组有两种方法:倍增算法,DC3算法。
其中,倍增算法的时间复杂度是O(NlogN)的,程序简单,算法过程易于理解。而DC3算法的时间复杂度是O(N),数据量大的时候,效率比倍增算法有显著提升,但是缺点在于DC3算法原理较难理解,代码冗长。所以,这里我们讲解倍增算法。
下面进入正题(为了防止格式错乱,采用图片的形式来讲解)。
Code
#include
写在最后
后缀数组的精华在于用sa数组求出height数组,而height数组有着各式各样的性质和用法,我将在下期为大家带来。
【信息学竞赛从入门到巅峰】,一个专注于分享OI/ACM常用算法及知识的公众号。