加了一点自己对高度数组的理解:
height 数组:定义 height[i]=suffix(sa[i-1])和 suffix(sa[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。那么对于 j 和 k,不妨设rank[j]<rank[k],
则有以下性质:
suffix(j) 和suffix(k)的最长公共前缀height[rank[j]+1],height[rank[j]+2], height[rank[j]+3], … ,height[rank[k]]中的最小值。
那么应该如何高效的求出 height 值呢?
如果按 height[2],height[3],……,height[n]的顺序计算,最坏情况下时 间 复 杂 度 为 O(n2) 。 这 样 做 并 没 有 利 用 字 符 串 的 性 质 。 定 义h[i]=height[rank[i]],也就是suffix(i)和在它前一名的后缀的最长公共前缀。
h 数组有以下性质:
h[i]≥h[i-1]-1
证明:
设 suffix(k)是排在 suffix(i-1)前一名的后缀,则它们的最长公共前缀是h[i-1]。
当h[i-1]>1时,我们不妨设suffix(k) 为”abcee…”suffix(i-1)为 “abdee…”,前后对照可知它们的最长公共前缀长度为2,那我们现在来考虑suffix(i)=”bdee”,那么排在它前面的是哪一个呢,其实我们不得而知,但是我们知道一个下界,suffix(k+1)=”bcee” 已经给我们提供了一个下界。
假如suffix(k+1)刚好排在suffix(i)的前一个,那么他们的最长公共前缀=1,此时h[i]=h[i-1]-1。如果suffix(k+1)不排在suffix(i)的前一个,而是前几个,可知在suffix(k+1)和suffix(i)之间插进了一个suffix(l),可想而知suffix(l)既要比suffix(k+1)大,又要比suffix(i)小,那么它的第一个字符一定是’b’,第二个字符一定在’c’和’d’之间,后面的不用考虑可知suffix(l)与suffix(i)的最长公共前缀>=suffix(k+1)与suffix(i)的最长公共前缀,既h[i]≥h[i-1]-1恒成立。
当h[i-1]<=1时,h[i-1]-1<=0,由h[]数组的定义可知,h[i]>=0,所以h[i]≥h[i-1]-1恒成立。
按照 h[1],h[2],……,h[n]的顺序计算,并利用 h 数组的性质,时间复杂度可以降为 O(n)。