后缀数组之精髓——height数组

作者: 信息学小屋 | 来源:发表于2020-05-03 21:01 被阅读0次

上期我们介绍了后缀数组中代码最难写的一部分,今天我们来讲解一下后缀数组中最精髓的一部分——height数组的求解。
【进阶】字符串问题一大利器——后缀数组详解
(附上sa数组求法的讲解)

几个共识

和之前一样,为了后文方便讲解,我们先来达成几个共识。

1、height[i]表示后缀sa[i-1]和后缀sa[i]的最长公共前缀。换句话说,height数组表示排名相邻的两个后缀的最长公共前缀。

2、h[i]表达第i个后缀和排名在他之前一位的后缀的最长公共前缀,即

性质及证明

防止证明过程中公式排版出错,这里仍然采用图片的形式讲解

性质及证明

求解height

我们很容易想到一种朴素的暴力算法,直接在每两个排名相邻的后缀之间枚举求解。但是这种算法最坏情况下的复杂度是O(N^2)的,而且完全没有利用后缀数组的性质。

下面,我们来讲解一种时间复杂度为O(N)的巧妙求法。

利用h数组的性质,我们按照排名的顺序来求解height数组。每次先把长度减1后,循环暴力扩展,并且把求出来的h[i]拷贝到height[rank[i]]即可。由于字符串的长度最大为N,最多进行N次减1操作,所以总计算次数是O(N)级别的。

Code

void height_get(int *r,int n) {
//r为字符串原串,n为字符串长度。
//此处的字符串为添加最小元素后的字符串。
    int k=0;
    for (int i=0;i<n;++i)rank[sa[i]]=i;
    for (int i=0;i<n;++i)
    {
        if (k)k--;
        int j=sa[rank[i]-1];
        while (r[i+k]==r[j+k])k++;
        height[rank[i]]=k;
    }
}//求最长公共前缀,利用h[i]>=h[i-1]-1

写在最后

后缀数组算法的重点在于求解sa数组、rank数组和height数组。有了这三个数组,我们就可以在字符串的世界自由玩耍了【滑稽】。

下期,我将为大家带来后缀数组的经典应用。

【信息学竞赛从入门到巅峰】,一个专注于分享OI/ACM常用算法及知识的公众号。

相关文章

  • 后缀数组之精髓——height数组

    上期我们介绍了后缀数组中代码最难写的一部分,今天我们来讲解一下后缀数组中最精髓的一部分——height数组的求解。...

  • 字符串

    字符串DP 字符串匹配 后缀数组 后缀数组的注意点:1 两个串拼接在一起。2 height数组的性质。POJ 15...

  • 单字符串问题?后缀数组来啦!

    前两期,我们重点介绍了后缀数组中sa、rank、height数组的求法。这些数组都具有优秀的性质,我来向大家介绍几...

  • 后缀树(suffix tree & array)

    定义:后缀数组(suffix array)是将字符串的所有后缀进行排序放入数组中。后缀树(suffix tree)...

  • 后缀数组

    一、定义 对于长度为n的文本串T[1...n],T的后缀是指从第i个字符开始到T的末尾所形成的子串T[i...n]...

  • 后缀数组

    http://uoj.ac/problem/35

  • 后缀数组1模板(强推罗XX的论文,贼棒)

    先%罗DADA建议按照论文手推,更易明白再%kuangbin大神 1、什么是后缀数组 后缀数组是后缀树的替代品,十...

  • 指针数组与数组指针

    指针数组与数组指针 这两个名词乍一看很相似,很让人分不清什么意思?其实主要看后缀名就可以了。指针数组,后缀为数组,...

  • 后缀数组模板

    来自dzj

  • php基础精粹

    PHP php数组 php数组之索引数组初始化 PHP数组之索引数组赋值 PHP数组之访问索引数组内容 PHP数组...

网友评论

    本文标题:后缀数组之精髓——height数组

    本文链接:https://www.haomeiwen.com/subject/mivjghtx.html