后缀数组的一些应用

  1.求重复子串:

  (1).可重叠最长重复子串

  做法简单,只要求出height数组中的最大值即可。首先求最长重复子串,等价与求两个后缀数组的最长公共前缀。

  (2).不可重叠最长重复子串

  把排序后的后缀分成若干组,其中每组的后缀之间的height值不小于k。例如,字符串为“aabaaaab”,当k=2时,后缀分成4组,如图所示:

  

  有希望成为最长公共前缀不小于k的两个后缀一定在同一组。然后对于每组后缀,只须判断每个后缀的sa 值的最大值和最小值之差是否不小于k如果有一组满足,则说明存在,否则不存在。

  (3).子串的个数

  求不相同的子串的个数。

  如果所有的后缀按 suffix[sa[1]],suffix[sa[2]],suffix[sa[3]],...,suffix[sa[n]]这样的顺序计算,可以看出每次加进来的后缀suffix[sa[k]],就产生了n-sa[k]+1个新的字符串,其中有height[k]个是和前一个后缀重复的,所以每个后缀贡献 n-sa[k]+1-height[k] 个字符串。最后结果累加得到。

  2.两个字符串的相关问题。

  这类问题的一个常用做法是,先把两个字符串接一起,然后求后缀数组和height数组,然后利用height数组求解。

  (1).最长公共子串

  求字符串A和B的最长公共子串等价与求A的后缀和B的后缀的最长公共前缀。

  由于要计算A的后缀和B的后缀的最长公共前缀,所以先将第二个字符串接在第一个字符串后面中间用一个没有出现过的字符隔开,再求这个新的字符串的后缀数组。以A为 “aaaba”,B为“abaa”为例:

  

    那么是不是所有的height值中的最大值就是答案呢?不一定,因为这两个后缀可能来自同一个字符串。所以实际上,只有suffix[i-1]和suffix[i]不是来自同一个字符串,height[i]才是符合条件的。

  

原文地址:https://www.cnblogs.com/yongren1zu/p/3239428.html