yy浅谈后缀数组

后缀数组是一种很优美的数组结构,基本上可以完全替代后缀数,后缀数组无论是在内存的占用或者是时间复杂度都和后缀树差不多,但是操作性比后缀树好很多。

后缀数组可以说是字符串处理的神奇啊!想的到的,想不到的都可以处理。

后缀数组的应用也是十分的广泛。后缀数组普遍可以通过O(nlogn)的复杂度解决很多问题。

一下是一些例题和后缀数组的一些应用。

1、求两个串后缀的最长公共前缀,height数组 。

2、单个字符串的问题:

(1)重复子串问题

 <1>可重叠的最长重复子串

  所谓的重复子串就至少出现两次在串中。其实根据height定义就可以算出来,height[i] rank[i]和rank[i-1]的最长共前缀,这个前缀其实就是一个子串,根据贪心,越是字典序靠近的两个串她们的公共前缀才会越长,那么就很显然了,只要求height[i]中的最大值即可。

 <2> 不可重叠的最长重复子串(poj1743)题解here

 这种题目一般只能用枚举答案,然后判断答案的正确性,用二分比较快。那么二分答案后,根据height分组(常用方法)只要存在这样的一组:其中SA[i]最大值和SA[i]最小值差大于等于枚举的长度那么这个长度就是可行的。自己想想为什么,在纸上画出根据rank排名的后缀就能分析出来。

<3> 出现至少k次最长重复可重叠子串(poj3261) 题解here

给出两个穿,求至少出现k次的最长重复子串,可以重叠。和上题相似。

(2)子串的个数问题(spoj694)题解 here

 不相同的子串出现的个数。题解讲的很清楚了。

(3)回文串

 最长回文子串(ural1297).给出一个串,求这个串的最长回文子串,

 我们可以将这个串倒置后加到原串后面,然后跑一边后缀数组,通过height来求最长的长度。

(4)连续重复子串问题

 <1>连续重复的子串(poj 2406)题解here

 <2>重复次数最多的连续重复子串(poj 3693) 题解here

 这题堪称神题,思维量不是一般大。

3、两个字符串的问题

 (1)公共子串(poj 2774)

 最长公共子串,只要将串加到原串后面,中间用分隔符分隔,跑一边后缀数组,然后根据rank虫小到大的枚举SA[i] 和 SA[i-1]找到分别在两个串中并且最大的L.

 (2)子串的个数(poj 3415)题解here

  长度不小于k的公共子串个数。

  非长好的题目,第一次用单调栈,题解将的很清楚了。

4、多个字符串的问题

 <1> 不小于k个串中的最长公共子串(poj 3294) 题解here

  这题异常的麻烦,堪称变态。二分长度,然后判断是否满足条件。判断的方法是根据height分组,对于每组进行处理,要判断是否有k个串可以用set保存对应SA[i]所属的子串,最后判断size是否>k.最蛋疼的是要按照字典序输出所有满足的串,处理起来不容易。

 <2> 每个字符串至少出现两次且不重叠的子串(spoj220) 题解 here

 给出n个串,求最长的公共子串使得这个串在每个串中都至少不重叠的出现两次。

 这题和上次做法相似,根据分组进行处理。

 <3> 出现或反转后出现在每个串中的最长公共子串

 其实只要将原串反转接到原串后整合成新的串,中间要用分隔符分隔。然后就是按照上题的做法处理。

神奇的后缀数组,非常的奇妙。

你可能感兴趣的:(yy浅谈后缀数组)