height[j]=lcp(j-1,j)即相邻排名的两个后缀的最长公共前缀。
height 数组:定义 height[i]=suffix(pos[i-1])和 suffix(pos[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀。那么对于 j 和 k,不妨设rank[j]<rank[k],则有以下性质:
suffix(i) 和 suffix(z) 的 最 长 公 共 前 缀(lcp) 为 height[rank[i]+1] , height[rank[i]+2], height[rank[i]+3], … ,height[rank[z]]中的最小值。
例如:字符串”babbaaab”,求后缀“baaab”和“bbaaab”的lcps.
即Lcp(‘baaab’, ‘bbaaab’)=1
求height的时间复杂度为O(n).
由(1)得:
由此定理,当后缀和相邻后缀的公共前缀为h时,后缀和其相邻后缀的公共前缀至少为h-1,利用这一性质可降低求height数组的时间复杂度为O(n)。
(1)求height数组,由于h每次循环至多减一,而s长为n,所以循环至多进行2*n次,时间复杂度为O(n).
/** 通过已排列的后缀数组Pos求lcp(j-1,j) **/
void GetHeight(char *s){
int n=strlen(s);
int *Rank=(int*)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)Rank[Pos[i]]=i;//Rank数组是Pos数组的逆
for(int h=0,i=1;i<n;i++){
if(Rank[i]==0){//字典序最小的数组其height无意义
height[0]=0;
continue;
}
while(s[i+h]==s[Pos[Rank[i]-1]+h])h++;
height[Rank[i]]=h;
if(h>0)h--;//由定理可得
}
}