下面借助一道题目和大家一起讨论:LCP及前缀 后缀数组的问题
题目:
food所有的组成情况如下:
d
f
fo
foo
food
o
od
oo
ood
按照字母顺序排列如上所示,现要求第k大的子串,例如第8大子串为oo
思路:蛮力就不说了,高级别考试肯定超时。这种题目是典型的利用后缀树和后缀数组解决的。
1. 将所有后缀列出来(prefix set)
d
od
ood
food
2. 对所有后缀子串进行排序,保存其在原来子串中位置SA(suffix array)
d 4
food 1
od 3
ood 2
3. 对相邻两个子串,求其LCP,即最长公共前缀
d 0(自己)
food 0(food与d)
od 0(od与food)
ood 1(od与ood)
4. 求第8大的子串:strlen("d")+strlen("food")+strlen("od")=7
因此第8大的子串即为"ood"子串的第一个前缀
而ood的前缀为:
o
oo
ood
因此应该是o,but前面我们明明手算第8大是oo的呀?
稍等,还没结束呢,刚刚不是计算得出了LCP吗?它就被用在这个地方了,由于出现重复情况,因此我们必须将LCP剔除在外
即ood前缀的第1+LCP(ood)个,即ood的第2个前缀子串
好了,思路如上,大家有兴趣可以按照这个思路写实现代码~