Abstract 1 Introduction 2 Sorting, BWT Inversion and Related Problems 3 Our Results 4 Conclusions References

On Inverting the Burrows-Wheeler Transform

Nicola Cotumaccio ORCID University of Helsinki, Finland
Abstract

We study the relationship between four fundamental problems: sorting, suffix sorting, element distinctness and BWT inversion. Our main contribution is an Ω(nlogn) lower bound for BWT inversion in the comparison model. As a corollary, we obtain a new proof of the classical Ω(nlogn) lower bound for sorting, which we believe to be of didactic interest for those who are not familiar with the Burrows-Wheeler transform.

Keywords and phrases:
Burrows-Wheeler transform, sorting, suffix array, element distinctness
Category:
Research
Copyright and License:
[Uncaptioned image] © Nicola Cotumaccio; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Theory of computation Design and analysis of algorithms
; Theory of computation Models of computation
Funding:
Funded by the Helsinki Institute for Information Technology (HIIT).
Editors:
Alessio Conte, Andrea Marino, Giovanna Rosone, and Jeffrey Scott Vitter

1 Introduction

Sorting is typically one of the introductory topics in a first course on algorithms and data structures. Knuth devotes almost four hundred pages to the problem in the The Art of Computer Programming [12] and Cormen et al. use insertion sort as a first example of an algorithm [3].

Consider a sorted alphabet (i.e., an alphabet endowed with a total order). The problem of sorting can be stated as follows.

Problem 1 (Sorting).

Given a string T=a1a2an, compute a permutation ψ of {1,2,,n} such that aψ(i)aψ(i+1) for every 1in1.

For example, if T=cdba, then the output of Problem 1 is the permutation ψ of {1,2,3,4} such that ψ(1)=4, ψ(2)=3, ψ(3)=1 and ψ(4)=2. Note that the permutation ψ of Problem 1 is uniquely defined if and only the ai’s are pairwise distinct. More generally, ψ becomes uniquely defined if we add the additional requirement that, for every 1in1, if aψ(i)=aψ(i+1), then ψ(i)<ψ(i+1). The permutation ψ that satisfies this additional requirement is the stable sort of T.

Both Knuth and Cormen at al.’s consider the comparison model, in which no restriction on the (possibly infinite) sorted alphabet is assumed, and the only way to obtain information on the mutual order between the characters in T is by solving queries c(i,j) of the following type: given 1i,jn, decide whether aiaj. We assume that each query c(i,j) takes O(1) time.

In the comparison model, the (worst-case) complexity of Problem 1 is Θ(nlogn): there exist algorithms (e.g., merge sort, which computes the stable sort of T) solving Problem 1 in O(nlogn) time, and any algorithm solving Problem 1 has complexity Ω(nlogn). The (classical) proof of the Ω(nlogn) lower bound [12, 3] shows a stronger result: to solve Problem 1, in the worst case we need Ω(nlogn) queries c(i,j)’s, and this is true even if we know that the ai’s are pairwise distinct. In other words, Ω(nlogn) is not only an algorithmic lower bound, but it also captures the minimum number of operations required to have enough information for solving Problem 1.

The comparison model yields a simple, informative, and mathematically appealing setting for studying the complexity of sorting, but it can hardly be considered a realistic computational model. For example, if the ai’s are known to be integers in a polynomial range, Problem 1 can be solved in O(n) time via radix sort, which also computes the stable sort of T [10].

The landscape becomes more complex if one considers alternative models of computations. On the one hand, it is possible to obtain models that are more flexible than the comparison model by allowing more complex queries in O(1) time. Assume that the alphabet is the set of all real numbers, and consider the function f(x,y)=xy. In the comparison model, in O(1) time we can test whether f(x,y)0 for any choice of x,y{a1,a2,,an}. In the linear decision tree model, one is allowed more general tests of the type f(x1,x2,,xn)0, where we consider a linear function f(x1,x2,,xn)=c0+c1x1+c2x2++cnxn. In the algebraic decision tree model, we can choose f(x1,x2,,xn) to be an arbitrary polynomial. Even if the linear decision tree model and the algebraic decision tree model are more general than the comparison model, the complexity of Problem 1 in all these models is still Θ(nlogn) [4, 1]. On the other hand, it is possible to consider (realistic) variants of the RAM model. In the word-RAM model with word size wlogN, where N is the size of the input, the complexity of Problem 1 is still open, even though it is known to be o(nlogn) [8, 9]. Other variants of these models are possible, but we will focus only on the comparison model and the case of integers in a polynomial range, which are arguably the most common settings in the literature.

In this paper, we show that the complexity of Problem 1 (Sorting) is the same as the complexity of other fundamental problems: suffix sorting, element distinctness and BWT inversion. The complexity of these problems in Θ(nlogn) in the comparison model and Θ(n) in the case of integers in a polynomial range. Our main contribution is an Ω(nlogn) lower bound for BWT inversion in the comparison model (Theorem 1). We also show that Theorem 1 implies a new proof of the classical Ω(nlogn) lower bound for sorting (Corollary 2), which we believe to be of didactic interest for those who are not familiar with the Burrows-Wheeler transform.

2 Sorting, BWT Inversion and Related Problems

Problem 1 is closely related to several fundamental problems. Here are some examples.

Problem 2 (Suffix sorting).

Given a string T=a1a2an, compute the permutation ψ of {1,2,,n} such that aψ(i)aψ(i)+1an1an is the i-th lexicographically smallest suffix of T for every 1in.

For example, if T=banana, then the output of Problem 2 is the permutation ψ of {1,2,3,4,5,6} such that ψ(1)=6, ψ(2)=4, ψ(3)=2, ψ(4)=1, ψ(5)=5 and ψ(6)=3. Note that ψ is uniquely defined because the suffixes of a string are pairwise distinct.

Problem 3 (Element distinctness).

Given a string T=a1a2an, decide whether there exist 1i<jn such that ai=aj.

For example, if T=cdba, then the output of Problem 3 is “no”.

The complexity of Problems 2 and 3 is Θ(n) in the case of integers in a polynomial range, and Θ(nlogn) in the comparison model. Let us show how to obtain these bounds by reducing these problems to Problem 1 (Sorting).

Let us consider the case of integers in a polynomial range.

  • Problem 2 can be solved in O(n) time by using any linear-time algorithm for building the suffix array (see [15] for a survey). Historically, the linear time complexity was first proved by Farach, who solved the more general problem of building the suffix tree of a string in linear time [5]. Conceptually, the easiest algorithm is probably Kärkkäinen et al.’s algorithm [11].

  • Problem 3 can be solved in O(n) time by first computing a permutation ψ as in Problem 1 (Sorting) and then checking in O(n) time if there exists 1in1 such that aψ(i)=aψ(i+1).

Let us consider the comparison model.

  • On the one hand, Problem 2 can be solved in O(nlogn) time by (i) sorting the ai’s via any O(nlogn) comparison-based algorithm, (ii) replacing each ai with its rank in the sorted list of all ai’s (which does not affect the mutual order of the suffixes) and (iii) applying any O(n) suffix sorting algorithm mentioned earlier. On the other hand, to solve Problem 2 we need Ω(nlogn) queries c(i,j)’s in the worst case, and the same lower bound is true even if we know that the ai’s are pairwise distinct. Indeed, given the permutation ψ of Problem 2, we have aψ(i)aψ(i+1) for every 1in1 (because the suffix aψ(i)aψ(i)+1an1an is lexicographically smaller than the suffix aψ(i+1)aψ(i+1)+1an1an), so ψ is also a correct output for Problem 1, and the conclusion follows from the lower bound for Problem 1 mentioned earlier.

  • On the one hand, Problem 3 has complexity O(nlogn): we can argue as in the case of integers in a polynomial range, but we use any O(nlogn) comparison-based algorithm to compute a permutation ψ as in Problem 1. On the other hand, to solve Problem 3 we need Ω(nlogn) queries c(i,j)’s in the worst case, as we show next. Fix an integer n, and consider an algorithm that solves Problem 3 for every string T=a1a2an. Let f(n) be the number of queries c(i,j)’s solved by the algorithm in the worst case. If the ai’s are pairwise distinct, the permutation ψ of Problem 1 is uniquely defined, and the algorithm for Problem 3 must return “no”. To this end, the algorithm must solve the query c(ψ(i+1),ψ(i)) for every 1in1 because otherwise the algorithm could not infer that aψ(i)aψ(i+1) from the other queries that it solves and so it would not have enough information to solve Problem 3 correctly on input T. Consequently, if for every query c(i,j) solved by the algorithm we also consider the query c(j,i), we obtain at most 2f(n) queries. In particular, we consider both the query c(ψ(i+1),ψ(i)) and the query c(ψ(i),ψ(i+1)) for every 1in1, from which we can infer that aψ(i)<aψ(i+1) for every 1in1. We conclude that at most 2f(n) queries c(i,j)’s are sufficient in the worst case to compute ψ and so solve Problem 1 for every T=a1a2an in which the ai’s are pairwise distinct. Hence, we obtain f(n)=Ω(nlogn) from the lower bound for Problem 1 mentioned earlier.

Let us show that Problem 1 is related to another fundamental problem in string processing and compression. To this end, we need to introduce the Burrows-Wheeler transform (BWT) of a string [2]. Let S=b1b2bn be a string such that bn=$, where $ is a special character such that (i) $ does not occur anywhere else in the string and (ii) $ is smaller than all the other characters. For example, we can consider the string S=banana$ (where n=7). For 1in, let Si=bibi+1bnb1b2bi1 be the i-th circular suffix of S. For example, if S=banana$, we have S1=banana$, S2=anana$b, S3=nana$ba, S4=ana$ban, S5=na$bana, S6=a$banan and S7=$banana. Note that the circular suffixes of S are pairwise distinct because $ occurs in a different position in each of them.

Table 1: The Burrows-Wheeler transform of banana$.

We build the square matrix M of size n×n such that, for every 1in, the i-th row Ri[1,n] is equal to i-th (lexicograhically) smallest circular suffix of S (see Table 1 for the matrix M of size 7×7 obtained from S=banana$). Note that R1=bnb1b2bn1=Sn because bn=$ is the smallest character.

For 1in, let Ci[1,n] be the i-th column of M from left to right. Notice that every Ci is a rearrangement of the characters in S. Let F=C1 and L=Cn be the first column and the last column of M, respectively. In Table 1, we have F=$aaabnn and L=annb$aa. Note that F can be obtained by sorting the characters of S. By definition, the Burrows-Wheeler transform 𝖡𝖶𝖳[S] of S is the column F, that is, 𝖡𝖶𝖳[S]=F=Cn. In Table 1, we have 𝖡𝖶𝖳[S]=annb$aa.

Crucially, the Burrows-Wheeler transform 𝖡𝖶𝖳[S] of a string S is an encoding of the string: given 𝖡𝖶𝖳[S], we can retrieve the string S. In Table 1, given 𝖡𝖶𝖳[S]=annb$aa, we can retrieve S=banana$. To prove this, we only need to show that from 𝖡𝖶𝖳[S] we can retrieve the matrix M, because then the unique row of the matrix ending with $ yields the original string S. We can retrieve M by computing all columns Ci’s. We know that Cn=𝖡𝖶𝖳(S), and we can retrieve C1 by sorting all characters in Cn. Let us show how to retrieve C2. We know Cn and C1, so we know all pairs of consecutive characters in S. If we sort these pairs lexicographically and we pick the last element of each pair, we retrieve C2. In Table 1, all pairs of consecutive characters in S are a$, na, na, ba, $b, an, an. By sorting these pairs, we obtain $b, a$, an, an, ba, na, na, and by picking the last element of each pair, we can infer that C2=b$nnaaa. Let us show how to retrieve C3. We know Cn, C1 and C2, so we know all triples of consecutive characters in S. If we sort these triples lexicographically and we pick the last element of each triple, we retrieve C3. In Table 1, all triples of consecutive characters in S are a$b, na$, nan, ban, $ba, ana, ana. By sorting these triples, we obtain $ba, a$b, ana, ana, ban, na$, nan, and by picking the last element of each triple, we can infer that C3=abaan$n. In the same way, we can retrieve C4,C5,,Cn1.

Since 𝖡𝖶𝖳(S) is an encoding of S, we can store 𝖡𝖶𝖳(S) instead of S without losing information. The reason why storing 𝖡𝖶𝖳(S) may be more beneficial than storing S is that the string 𝖡𝖶𝖳(S) tends to be repetitive if in S several substrings have multiple occurrences, so we can exploit the repetitiveness of S to compress 𝖡𝖶𝖳(S). This property motivated the introduction of the Burrows-Wheeler transform in the original paper [2] and can be stated in precise mathematical terms via the notion of entropy [13]. Surprisingly, it is also possible to solve pattern matching on the original string by augmenting the compressed representation of the Burrows-Wheeler transform with space-efficient data structures, thus obtaining the FM-index [6].

We described an (inefficient) algorithm to invert the Burrows-Wheeler transform. Let us state the problem formally.

Problem 4 (BWT inversion).

Given a string T=a1a2an such that T=𝖡𝖶𝖳(S) for some ($-terminated) string S, compute S.

For example, if T=annb$aa, then S=banana$ (see Table 1).

3 Our Results

In this section, we show that the complexity of Problem 4 in Θ(nlogn) in the comparison model and Θ(n) in the case of integers in a polynomial range. The only bound that cannot be inferred from the original paper on the Burrows-Wheeler transform [2] is the Ω(nlogn) lower bound in the comparison model. Notice that the four problems considered in this paper have the same complexity.

To prove the Ω(nlogn) bound for Problem 4, we will proceed differently from Problems 2 and 3. We will prove the lower bound directly, without relying on the lower bound for Problem 1 (Sorting). Then, we will use the lower bound for Problem 4 (BWT inversion) to infer the lower bound for Problem 1 (Sorting). In addition to establishing interesting relationships between fundamental problems, our approach yields a new proof of the celebrated Ω(nlogn) bound for sorting, which we believe to be of didactic interest.

Let us start with the lower bound for BWT inversion.

Theorem 1.

In the comparison model, to solve Problem 4 we need Ω(nlogn) queries c(i,j)’s in the worst case. The same lower bound holds even if we know that the ai’s are pairwise distinct.

Proof.

Fix an integer n. Consider n1 distinct characters b1,b2,,bn1 such that $<b1<b2<<bn1. Then, the set:

𝒮={bϕ(1)bϕ(2)bϕ(n1)$| ϕ is a permutation of {1,2,,n1}}

has size (n1)!. For every S𝒮, the string 𝖡𝖶𝖳(S) is an encoding of S, so the set:

𝒯={𝖡𝖶𝖳(S)|S𝒮}

has also size (n1)!. Notice that for every string T=a1a2an, if T𝒯, then the ai’s are pairwise distinct.

Consider any algorithm solving Problem 4 for every input T=a1a2an𝒯. The algorithm can gather information on the mutual order between the ai’s only by solving queries c(i,j)’s. The decision on the next query c(i,j) can depend on the outcome of the previous queries c(i,j)’s, so we can describe the behavior of the algorithm on all inputs T𝒯 through a decision tree (see Figure 1 for the case n=4). Since the algorithm correctly solves Problem 4 for every input T=a1a2an𝒯, then the outcome of all queries c(i,j)’s on a path from the leaf to a roof cannot be consistent with two distinct elements of 𝒯, otherwise the algorithm would not have enough information to compute S . For example, in Figure 1, if the output of “a1a3” is “no” and then the output “a1a2” is “yes”, then the algorithm must necessarily solve an additional query c(i,j): both T1=b1b3$b2 and T2=b2b3b1$ are strings in 𝒯 for which ¬(a1a3)(a1a2), and we have T1=𝖡𝖶𝖳(S1) and T2=𝖡𝖶𝖳(S2) for two distinct S1,S2𝒮, where S1=b2b3b1$ and S2=b3b1b2$.

Assume that the longest path in the tree consists of k edges. Then, the number of paths from the root to a leaf is upper bounded by 2k, so we must have 2k(n1)!, which implies k=Ω(nlogn). This means that there exists T𝒯 for which the algorithm needs to solve Ω(nlogn) queries c(i,j)’s.

Figure 1: The decision tree of a possible algorithm solving Problem 4 (see the proof of Theorem 1) for n=4. We have |𝒮|=|𝒯|=(41)!=6. The tree describes the sequence of all queries c(i,j)’s for every input T=a1a2a3a4𝒯. Recall that we assume $<b1<b2<b3. We have 𝖡𝖶𝖳(b1b2b3$)=b3$b1b2, 𝖡𝖶𝖳(b1b3b2$)=b2$b3b1, 𝖡𝖶𝖳(b2b1b3$)=b3b2$b1, 𝖡𝖶𝖳(b2b3b1$)=b1b3$b2, 𝖡𝖶𝖳(b3b1b2$)=b2b3b1$ and 𝖡𝖶𝖳(b3b2b1$)=b1b2b3$. Every element of 𝒯 corresponds to a path from the root to a leaf.

The proof of Theorem 1 is similar to the classical proof of the Ω(nlogn) lower bound for sorting [12, 3]. In the classical proof, one typically uses the fact that a binary tree with n! leaves must have height at least log(n!). Here we used a slightly more direct pigeonhole argument to prove the inequality 2k(n1)!. The worst-case entropy of a set S is log|S| by a similar pigeonhole argument [14], so one may argue that in the proof of Theorem 1 we used an entropy-based argument. This appears to establish an interesting analogy because we have already mentioned that the compressibility of the Burrows-Wheeler transform can be described through the notion of entropy [13].

Now, let us describe an efficient algorithm to solve Problem 4. The original paper by Burrows and Wheeler [2] follows an approach based on a permutation called LF-mapping. Here we will use a different approach based on the permutation ψ, which is the inverse of the LF-mapping. The permutation ψ plays a crucial role in compressed suffix arrays [7], and it captures the connection between Problem 4 (BWT inversion) and Problem 1 (Sorting) more explicitly. We are given T=a1a2an such that T=𝖡𝖶𝖳(S) for some S=b1b1bn, where bn=$, and we need to compute S. By definition, T=L, where L is the last column of the matrix M, so we know that L=a1a2an and we must retrieve S.

Let ψ be the stable sort of L (see Problem 1 and Table 1). Since $ is the smallest character, we have L[ψ(1)]=$=bn. We will prove that bi=L[ψi+1(1)] for every 1in1. For example, in Table 1 we have b1=L[ψ2(1)]=L[4]=b, b2=L[ψ3(1)]=L[7]=a, b3=L[ψ4(1)]=L[3]=n, b4=L[ψ5(1)]=L[6]=a, b5=L[ψ6(1)]=L[2]=n and b6=L[ψ7(1)]=L[1]=a, so S=banana$. After computing ψ, we can retrieve all the bi’s in O(n) time by computing all the powers ψi+1(1)’s. In the comparison model, we can compute ψ in O(nlogn) time, and in the case of integers in a polynomial range we can compute ψ in O(n) time, so the complexity of Problem 4 is O(nlogn) in the comparison model and O(n) in the case of integers in a polynomial range. We are left with proving that bi=L[ψi+1(1)] for every 1in1.

Let A[1,n] be the array such that, for every 1in, the row Ri of the matrix M is equal to the circular suffix SA[i] (see Table 1). Then, A[1,n] yields a permutation of {1,2,,n}. Moreover, we have F[i]=bA[i] and L[i]=bA[i]1 for every 1in, where we assume b0=bn. In particular, bA[ψ(1)]1=L[ψ(1)]=$, so we have A[ψ(1)]=1 and 2A[ψ(i)]n for 2in. Notice that A yields a permutation of {1,2,,n}. From R1=Sn we obtain A[1]=n.

Let us prove that A[ψ(i)]=A[i]+1 for every 2in (for example, in Table 1 we have A[ψ(2)]=A[1]=7=6+1=A[2]+1). Fix a character c$ that occurs in S. Let 1i1n be the smallest integer such that F[i1]=c, and let 1i2n be the largest integer such that F[i2]=c. We only have to prove that A[ψ(i)]=A[i]+1 for every i1ii2, because by picking all possible values c$ from smallest to largest we cover every i between 2 and n (i=1 corresponds to $). Let us prove that A[ψ(i)]=A[i]+1 for every i1ii2. From the definitions of i1 and i2 we obtain that in every row of M and in every column of M there are exactly i2i1+1 characters equal to c, and in particular L[ψ(i1)]=L[ψ(i1+1)]==L[ψ(i21)]=L[ψ(i2)]=c. Since ψ is the stable sort of L, we obtain ψ(i1)<ψ(i1+1)<<ψ(i21)<ψ(i2). This implies that SA[ψ(i1)] is lexicographically smaller than SA[ψ(i1+1)], SA[ψ(i1+1)] is lexicographically smaller than SA[ψ(i1+2)], , SA[ψ(i21)] is lexicographically smaller than SA[ψ(i2)]. We have bA[ψ(i)]1=L[ψ(i)]=c for every i1ii2, so we conclude that SA[ψ(i1)]1 is lexicographically smaller than SA[ψ(i1+1)]1, SA[ψ(i1+1)]1 is lexicographically smaller than SA[ψ(i1+2)]1, , SA[ψ(i21)]1 is lexicographically smaller than SA[ψ(i2)]1, where bA[ψ(i)]1=c for every i1ii2. At the same time, for every 1in we have bA[i]=c if and only if i1ii2, and SA[i1] is lexicographically smaller than SA[i1+1], SA[i1+1] is lexicographically smaller than SA[i1+2], , SA[i21] is lexicographically smaller than SA[i2]. We obtain A[ψ(i)]1=A[i] for every i1ii2, so A[ψ(i)]=A[i]+1 for every i1ii2, as claimed.

Let us prove that A[ψi(1)]=i for every 1in (for example, in Table 1 we have A[ψ2(1)]=A[ψ(5)]=A[4]=2). We proceed by induction on i. For i=1, we know that A[ψ(1)]=1. Now assume that 2in. By the inductive hypothesis, we know that A[ψi1(1)]=i1. In particular, A[ψi1(1)]n, so 2ψi1(1)n and we obtain A[ψi(1)]=A[ψ(ψi1(1))]=A[ψi1(1)]+1=(i1)+1=i.

We are now ready to prove the main claim. We have bi=b(i+1)1=bA[ψi+1(1)]1=L[ψi+1(1)] for every 1in1.

We conclude our paper by showing that Theorem 1 implies a new proof of the lower bound for sorting.

Corollary 2.

In the comparison model, to solve Problem 1 we need Ω(nlogn) queries c(i,j)’s in the worst case. The same lower bound holds even if we know that the ai’s are pairwise distinct.

Proof.

Consider any algorithm solving Problem 4 for every input T=a1a2an such that the ai’s are pairwise distinct. Since the ai’s are pairwise distinct, the permutation ψ of Problem 1 is uniquely defined, and ψ is also the stable sort of T. Let f(n) be the number of queries c(i,j)’s solved by the algorithm in the worst case to compute ψ. Assume that T=𝖡𝖶𝖳(S), where S=b1b2bn. After computing ψ, we can compute S in O(n) time (because bi=T[ψi+1(1)] for every 1in1, as we have seen before) without solving any additional query c(i,j). Consequently, f(n) queries are sufficient in the worst case to solve Problem 4 for every input T=a1a2an such that the ai’s are pairwise distinct. By Theorem 1, we conclude f(n)=Ω(nlogn).

4 Conclusions

In this paper, we have shown that, in the comparison model, inverting the Burrows-Wheeler transform has complexity Θ(nlogn). As a corollary, we have obtained a new proof of the Ω(nlogn) sorting lower bound. Our main goal was to highlight how the ideas behind the Burrows-Wheeler transform are deeply intertwined with the most fundamental results in Computer Science.

References

  • [1] Michael Ben-Or. Lower bounds for algebraic computation trees. In Proceedings of the fifteenth Annual ACM Symposium on Theory of Computing, pages 80–86, 1983.
  • [2] Michael Burrows and David J. Wheeler. A block-sorting lossless data compression algorithm. Technical report, Systems Research Center, 1994.
  • [3] Thomas H Cormen, Charles E Leiserson, Ronald L Rivest, and Clifford Stein. Introduction to algorithms. MIT press, 2022.
  • [4] David P Dobkin and Richard J Lipton. On the complexity of computations under varying sets of primitives. Journal of Computer and System Sciences, 18(1):86–91, 1979. doi:10.1016/0022-0000(79)90054-0.
  • [5] Martin Farach. Optimal suffix tree construction with large alphabets. In Proceedings 38th Annual Symposium on Foundations of Computer Science, pages 137–143. IEEE, 1997. doi:10.1109/SFCS.1997.646102.
  • [6] Paolo Ferragina and Giovanni Manzini. Opportunistic data structures with applications. In Proceedings 41st Annual Symposium on Foundations of Computer Science, pages 390–398. IEEE, 2000. doi:10.1109/SFCS.2000.892127.
  • [7] Roberto Grossi and Jeffrey Scott Vitter. Compressed suffix arrays and suffix trees with applications to text indexing and string matching. In Proceedings of the thirty-second Annual ACM Symposium on Theory of Computing, pages 397–406, 2000.
  • [8] Torben Hagerup. Sorting and searching on the word RAM. In STACS 98: 15th Annual Symposium on Theoretical Aspects of Computer Science Paris, France, February 25–27, 1998 Proceedings 15, pages 366–398. Springer, 1998. doi:10.1007/BFB0028575.
  • [9] Yijie Han. Deterministic sorting in O(nloglogn) time and linear space. Journal of Algorithms, 50(1):96–105, 2004. doi:10.1016/J.JALGOR.2003.09.001.
  • [10] John E Hopcroft, Jeffrey D Ullman, and Alfred Vaino Aho. Data structures and algorithms, volume 175. Addison-wesley Boston, MA, USA:, 1983.
  • [11] Juha Kärkkäinen, Peter Sanders, and Stefan Burkhardt. Linear work suffix array construction. Journal of the ACM (JACM), 53(6):918–936, 2006. doi:10.1145/1217856.1217858.
  • [12] Donald E Knuth. The Art of Computer Programming: Sorting and Searching, volume 3. Addison-Wesley Professional, 1998.
  • [13] Giovanni Manzini. An analysis of the Burrows-Wheeler transform. Journal of the ACM (JACM), 48(3):407–430, 2001. doi:10.1145/382780.382782.
  • [14] Gonzalo Navarro. Compact data structures: A practical approach. Cambridge University Press, 2016.
  • [15] Simon J Puglisi, William F Smyth, and Andrew H Turpin. A taxonomy of suffix array construction algorithms. ACM Computing Surveys (CSUR), 39(2):4–es, 2007.