Efficient Index for Square Pattern Matching
Abstract
A string is called a square if it can be written as the concatenation of two identical strings. Two strings and of the same length are said to square match if, for every substring of , it is a square if and only if the corresponding substring of is also a square. The square pattern matching problem asks for locating all substrings of a given text of length that square match a query pattern of length . This notion captures similarity in repetition structures and is motivated by applications in areas such as bioinformatics and music structure analysis.
In this paper, we introduce a novel technique, called the longest prefix square (LPS) encoding, which represents the square structure of a string as an integer array of the same length. We show that two strings square match if and only if they have identical LPS encodings. Based on this result, we construct an index solving the square pattern matching problem in time using bits of space, where occ denotes the number of occurrences of substrings in that square match . If the LPS encoding of is precomputed, the query time improves to .
Keywords and phrases:
string algorithms, pattern matching, indexing, squaresFunding:
Wing-Kai Hon: This work was supported by Taiwan NSTC Grant Number 113-2221-E-007-139.Copyright and License:
2012 ACM Subject Classification:
Theory of computation Pattern matchingAcknowledgements:
We thank the anonymous reviewers for their comments, which greatly strengthen our results.Editors:
Philip Bille and Nicola PrezzaSeries and Publisher:
Leibniz International Proceedings in Informatics, Schloss Dagstuhl – Leibniz-Zentrum für Informatik
1 Introduction
A string is called a square if it can be expressed as the concatenation of two identical non-empty strings, that is, . As a fundamental unit of repetition, squares have attracted considerable attention for decades, particularly in areas such as bioinformatics [14] and music structure analysis [20, 21]. Most existing studies focus on exact or approximate pattern matching, where the target substrings are required to be identical to, or differ slightly from, a given query pattern.
In this paper, we propose a new type of matching problem, called the square pattern matching problem. We say that two strings and of the same length are square matched if, for every substring of , it is a square if and only if the corresponding substring of is also a square. This notion of square match captures the idea that the two strings share identical repetition structures (or, equivalently, identical run structures [3]). The Square Pattern Matching problem is to locate all substrings of a given text that square match a query pattern .
Several studies on structural matching [1] have been proposed, including parameterized pattern matching [2], order-preserving matching [11, 8], Cartesian tree matching [18, 22], and substring consistent equivalence relation (SCER) matching [15, 9]. Recently, palindrome pattern matching [10, 17] has also been introduced. Our problem is inspired by this line of research and can be viewed as a structural counterpart in which the underlying property is repetition rather than palindromic symmetry.
Our core idea is to introduce a novel technique, called the longest prefix square (LPS) encoding, which encodes the repetition structure of a string into a sequence of integers of the same length. Using this encoding, we can verify whether two strings are square matched by simply comparing their LPS encodings. We further introduce the LPS index to locate all substrings of a given text of length that square match with a query pattern of length . The query can be answered in time using bits of space, where occ denotes the number of occurrences of substrings in that square match . If the LPS encoding of is precomputed, the query time improves to .
Our contributions can be summarized as follows:
-
LPS Encoding: We introduce the longest prefix square (LPS) encoding, which characterizes the square structure of a string by an integer array of the same length. We prove that two strings square match if and only if they have identical LPS encodings.
-
LPS Index Construction: We design algorithms to construct the LPS index, consisting of the LPS table and the diagonal trie. For a text of length , the LPS index can be constructed in preprocessing time.
-
LPS Index Compression: We compress the LPS index for a text of length from a naïve bit representation to bits, while preserving query efficiency.
The organization of the paper is as follows. Section 2 presents preliminary definitions. In Section 3, we introduce our main contribution, the LPS encoding and the LPS index, for solving the square pattern matching problem. Section 4 describes how to compress and construct the LPS index. Finally, Section 5 concludes the paper and discusses possible directions for future work.
2 Preliminaries
We consider a string of length , where each character is drawn from an alphabet of constant size . For any , we denote by the substring . If , we define to be the empty string.
The concatenation of two strings and is denoted by . If a string can be written as , where and are (possibly empty) strings, then and are called a prefix and a suffix of , respectively. A proper prefix (resp., proper suffix) of is a prefix (resp., suffix) of that is not equal to itself.
For a string and an integer , we denote by the string obtained by concatenating with itself times. If can be written as for a non-empty string and an integer , then is called non-primitive; otherwise, it is primitive.
2.1 Periodicity
If a string can be written as , where , is a non-empty string, and is a prefix of , then is called a period of . The shortest such string is called the root of .
The following is an important result on the periods of strings:
Theorem 1 (Fine-Wilf Theorem [5]).
Let be a string, and suppose that and are periods of . If , then is also a period of .
2.2 Squares
A string is called a square if it can be written as for a non-empty string . A square is called a primitive square if is primitive; otherwise, it is a non-primitive square.
The following is an important result on primitive squares:
Lemma 2 (Three Squares Lemma [4]).
Let , , be three prefixes of a string such that , , are primitive and . Then .
Corollary 3.
A string of length has at most prefixes that are primitive squares.
Proof.
When we arrange the primitive square prefixes of in increasing order of their lengths, their lengths must at least double for every two such prefixes (by Lemma 2).
2.3 Run structure
A run [13] in a string is represented by a tuple , where for a root of length , an integer , and is a prefix of ; furthermore, the interval needs to be maximal (where it cannot be extended to the left or to the right), so that and . For example, aabaabac has three runs: , , and , as shown in Figure 1.
The maximum number of runs in a string of length is [13] and can be identified in time for ordered alphabets [6].
We say that a position is covered by a run if and only if . It is easy to see that a square starts at position if and only if is covered by a run. Thus, we obtain the following lemma.
Lemma 4.
Let be a string of length . Each position (with ) is covered by at most runs.
Proof.
Assume that a position is covered by more than runs. Then there are more than primitive squares starting at , contradicting Corollary 3.
2.4 Model of Computation
Throughout this paper, we assume that the word size is large enough to hold the input size encoded in binary. In other words, when dealing with strings of length , will be sufficient. Furthermore, we assume the unit-cost word RAM model [7] as the model of computation, in which standard arithmetic and bitwise boolean operations on word-sized operands can be performed in constant time.
3 Longest Prefix Square (LPS) Index
In this section, we first formally define the problem under consideration. We then introduce several theorems and the LPS index for solving the problem. We begin by introducing a measure for verifying whether two strings have the same square structure, which is defined as follows.
Definition 5 (Square Match).
Let and be two strings of the same length. We say that and are square matched, if for every pair of positions , the substring is a square if and only if is a square.
Given a string and a query pattern , our goal is to locate all substrings of that are square matched with . We define the set of such locations as follows.
Definition 6 ().
Given a string of length and a query pattern of length , is the set of the positions of such that and are square matched, where .
We next describe how to verify whether two strings of length are square matched. A straightforward brute-force approach runs in time: there are substrings, and for each substring one can check whether it is a square in time using the KMP algorithm [12]. To reduce the time complexity, we introduce the LPS encoding technique.
Definition 7 (Longest Prefix Square (LPS)).
Let be a string of length . The longest prefix square (LPS) of is the longest prefix of that is a square. Formally, let
If , the LPS of is ; otherwise, the LPS is defined to be the empty string.
By computing the LPS length of each suffix of , we obtain the LPS array, defined as follows.
Definition 8 (LPS Array).
Let be a string of length . The LPS array of , denoted by , is defined such that for each , equals the length of the LPS of the suffix .
An example is shown in Figure 2(a). The array can be computed using Algorithm 1. Step 1 takes time [6]. Step 2 can be performed in time using bucket sort. In Step 3, each iteration processes at most runs by Lemma 4. Moreover, the runs covering all positions can be computed in total time using a sweep-line algorithm. Therefore, Step 3 takes time in total, and can be computed in time.
Given a string of length :
-
1.
Compute the run structure of .
-
2.
Sort all runs of in lexicographic order.
-
3.
For to do:
;
For all runs that cover position do:
;
| a | b | b | a | b | b | |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | |
| 0 | 2 | 0 | 0 | 2 | 0 | |
| 0 | 2 | 0 | 0 | 2 | 0 | |
| 0 | 2 | 0 | 0 | 2 | 0 | |
| 0 | 2 | 0 | 0 | 2 | 0 | |
| 6 | 2 | 0 | 0 | 2 | 0 |
The LPS array allows us to verify whether two strings are square matched by simply checking whether their LPS arrays are identical, as formalized in the following theorem.
Theorem 9.
The two strings and are square matched if and only if .
Proof.
() Suppose that and are square matched. By Definition 5, for every position and every , the substring is a square if and only if is a square. Hence, for each position , the maximum such is the same for and , implying that . Therefore, .
() We prove this direction by induction on the string length . Assume that . For the base cases, when , no square exists and . When , either or . In the former case, both and consist of two distinct characters; in the latter case, both consist of two identical characters. In either case, and are square matched.
Assume that the statement holds for all , and consider the case . Let and denote the strings obtained from and by removing their first character, respectively. Since the LPS array depends only on the suffixes starting at different positions, the last entries of coincide with those of , and similarly for . Therefore, we have . By the induction hypothesis, and are square matched, which implies that and are square matched.
It remains to show that, for every , the substring is a square if and only if is a square. Let . For every , the substring is a square if and only if is a square by Definition 8, and the statement holds trivially. For every , we prove the claim by contradiction. Without loss of generality, suppose that is a square while is not. We separate the discussion into two cases, which together cover all possibilities.
To give a better illustration, we will use several figures as an aid. In these figures, we use Color to represent substrings in the figures. For instance, Yellow denotes the substring colored in yellow. Substrings sharing the same color represent identical strings, and additional labels are sometimes used to distinguish different occurrences of the same substring.
Case 1: .
As shown in Figure 3(a), since is a square, it follows that
Hence, the substring is also a square.By the induction hypothesis, is a square as well. Moreover, since is a square, it follows that is a square, contradicting our assumption.
Case 2: .
As shown in Figure 3(b), we have the following three squares:
- Square 1:
-
.
- Square 2:
-
.
- Square 3:
-
.
Note that identical substrings are colored in the same color. To distinguish different occurrences of the same-colored substrings, we will use subscripts, such as , , and so on, for different substrings in red.
We first focus on the substring (denoted by ). By Square 1, occurs as a prefix of . Applying Square 2 and Square 1 repeatedly, we obtain (by Square 2) and (by Square 1). We continue this process until we obtain a substring whose ending position is greater than or equal to (denoted by in the example).
We divide at position into two substrings, denoted by and , and replace all occurrences of Red accordingly, as shown in Figure 3(b). We observe that there are multiple squares composed of and . These squares are marked by brackets of different colors in Figure 3(c). By the induction hypothesis, the corresponding substrings of are also squares and can be decomposed into and .
Finally, as shown in Figure 3(d), a sequence of and appears as a prefix of by Square 3. As indicated by the pink brackets, we have , which implies that is a square, contradicting our assumption.
The case where is empty, that is, when ends exactly at position , can be proved analogously and is therefore omitted.
In summary, both cases lead to a contradiction, and the proof completes.
Observe that the LPS array of coincides with the last entries of the LPS array of . This observation motivates the use of a two-dimensional table, called the LPS table (), to store the LPS arrays of all substrings of .
Definition 10 (LPS table).
Let be a string of length . The two-dimensional table is defined such that represents the length of the longest prefix square of the substring .
An example is illustrated in Figure 2(b). In particular, to reconstruct the LPS array of the substring , we consider the following diagonal of the LPS table:
The LPS table of requires bits of space to store and can be constructed in time.111In practice, the space can be reduced by a factor of two by storing only rows corresponding to even lengths, since for all odd . We defer the construction of the LPS table to Section 4.2.
Since the LPS table of contains the LPS arrays of all substrings of , we can answer by locating among those represented in the LPS table of . To support this operation efficiently, we construct an additional data structure: a trie built over all diagonals of the LPS table of . Equivalently, this trie stores the LPS arrays of all prefixes of .
Definition 11 (Diagonal Trie).
Let be a string of length , and let denote the LPS table of . For each position , consider the diagonal of defined by
The diagonal trie of is the compressed trie obtained by inserting all such diagonals, each terminated by a terminal symbol $, one for each .
Each edge stores the corresponding start and end positions in . Each internal node stores pointers to the leftmost and rightmost leaves of its subtree. Each leaf stores the associated position and a pointer to the next leaf in left-to-right order. The outgoing edges of each node are stored in a deterministic static linear-space dictionary [16], which supports worst-case lookup time.
Note that the edges of the diagonal trie only store references to entries of the LPS table; thus, access to the LPS table must be available. The following lemma summarizes the space usage of the diagonal trie and its construction time.
Lemma 12.
The diagonal trie of requires bits of space, in addition to the space required for the LPS table, and can be constructed in time.
Proof.
The diagonal trie is a compressed trie containing leaves, one for each diagonal of the LPS table (equivalently, one for each position of ). In a compressed trie, every internal node except the root has degree at least two. Hence, the number of internal nodes is at most , and the total number of nodes and edges is .
Each node and edge stores indices or pointers of size bits. Since the total number of nodes and edges is , the trie itself occupies bits. Moreover, the deterministic static dictionaries for the outgoing edges also require bits in total. Therefore, the diagonal trie requires bits of space.
To construct the trie, we insert all diagonals of the LPS table. The total length of all diagonals is , and thus the total insertion time is . Since each node is augmented with a deterministic static dictionary, and the total number of entries across all these dictionaries is , constructing all deterministic static dictionaries requires time [16] for any constant . We will choose . Since , this does not affect the overall time bound. Therefore, the construction time is .
Up to this point, the LPS index of consists of the following two components:
-
1.
the LPS table of ;
-
2.
the diagonal trie of the LPS table.
To answer , we first compute , and then traverse the diagonal trie of by scanning from right to left. If the traversal succeeds and terminates at a node (which may be an implicit node located in the interior of an edge), then for each leaf in the subtree rooted at this node, we insert the position into , where is the position stored at the leaf. Otherwise, we return the empty set.
We summarize the query time complexity of the above procedure as follows.
Theorem 13.
Given a string of length together with its LPS table and diagonal trie, and a query pattern of length , the set can be computed in time, where occ denotes the number of substrings of that square match with . If the array is given, the time complexity can be reduced to .
Proof.
Each node of the diagonal trie stores its outgoing edges in a deterministic static dictionary supporting worst-case query time [16]. Thus, retrieving the next edge during traversal takes time. Querying the pattern traverses at most nodes, resulting in a total time of . Traversing all leaves in the corresponding subtree takes time. If the array is not given, it can be computed in time using Algorithm 1. Therefore, the overall time complexity is .
An example is illustrated in Figure 2(c). The blue labels denote the node indices. Given , we have . We start from the root (), follow the edges to traverse , and eventually reach . From here on, we know that each leaf in the subtree rooted at witnesses a substring matching with . Each leaf stores the ending position of this substring, so subtracting from this ending position gives the starting position of the matching substring. By doing this for each leaf in this example, we form the set .
4 Compression and Construction of LPS Index
The LPS index of consists of the LPS table and the diagonal trie, where the former requires bits and the latter requires bits. In this section, we first present a compressed representation of the LPS table using bits, and then describe how to construct the LPS index of based on this compressed representation.
4.1 LPS Table Compression
We start from the well-known Three Squares Lemma (Lemma 2), which implies that there are only primitive squares in any fixed column of the LPS table of . We exploit this property by storing only the corresponding entries, instead of all entries.
We next introduce the following lemma to capture the relationship among these primitive squares.
Lemma 14.
Let and be two primitive strings. Suppose that is a non-primitive square and is a square, both of which are prefixes of a string , where and . Then either or holds.
Proof.
Assume that . Since has two periods and , and , it follows from Lemma 1 that has period . Hence, also has period , which implies that is not primitive, leading to a contradiction.
Let be the roots of the primitive-square prefixes of , sorted by increasing length. Lemma 14 implies that any prefix square must be shorter than . Therefore, for each primitive square, we only store the following information, which suffices to compute the LPS length of any entry in the column.
-
1.
, the root length of the -th smallest primitive-square prefix of ;
-
2.
, the maximum integer such that is a prefix of .
For each column of the LPS table, we store at most such doublets in a contiguous array by Lemma 2, and maintain the corresponding lengths in a dynamic fusion tree that supports -time rank queries using bits of space [19].222Since the set contains elements, each query takes time in the word-RAM model with word size .
To retrieve the value of , we first compute the number of elements in the column that are less than or equal to using a rank query. Suppose that the query returns . We then retrieve the doublet stored in . Finally, we compute as follows:
Since rank queries and access to the array both take time, it follows that can be computed in time. Therefore, the compressed LPS table preserves the query efficiency stated in Theorem 13.
4.2 LPS Index Construction
In this section, we first describe how to construct a compressed representation of the LPS table, where each column is represented using two auxiliary data structures: a dynamic fusion tree and an array storing primitive-square doublets.
For a fixed column of the LPS table, we initialize the array by setting
We then compute the failure function of the string using the KMP algorithm [12], where the value is defined to be the length of the longest proper prefix of that is also a suffix of . For , we compute the LPS of using as follows. Let be the last doublet stored in . We first determine whether is a square by checking whether divides . If this condition does not hold, we proceed to the next value of . Otherwise, we check whether the root length is equal to . If so, we increment by :
Otherwise, we append a new doublet:
Finally, we construct a dynamic fusion tree on the set of values , thereby completing the construction of this column. After constructing the compressed LPS table, we build the diagonal trie as described in Lemma 12, which completes the construction of the LPS index.
We summarize the construction of the LPS index below.
Theorem 15.
Given a string of length , the LPS index of can be constructed in time and occupies bits of space.
Proof.
For a fixed column of the LPS table, the associated information can be computed in time by applying the KMP algorithm [12] to the suffix . The dynamic fusion tree corresponding to can also be constructed in time [19].333A naïve approach inserts the elements one by one, each in time (as ). Since there are columns in total, the entire LPS table can be constructed in time. By Lemma 12, the diagonal trie can also be constructed in time. Therefore, the total construction time of the LPS index is .
For a fixed column of the LPS table, the array storing the primitive-square doublets requires bits of space, and the dynamic fusion tree requires bits of space. Therefore, summing over all columns, the compressed LPS table requires bits of space. The diagonal trie requires bits of space by Lemma 12. This completes the proof.
5 Conclusion
In this paper, we introduced a new type of structural matching problem, called Square Pattern Matching. We propose the LPS index that requires bits of space and finds all occurrences matching with a pattern of length in time. This running time can be reduced to time if the LPS array of the query pattern is given. This index is applicable to domains in which similarity in repetition structure is of interest, such as bioinformatics and music structure analysis.
Future work includes improving the time complexity of LPS array construction and exploring further compression of the LPS index.
References
- [1] Amihood Amir, Richard Cole, Ramesh Hariharan, Moshe Lewenstein, and Ely Porat. Overlap matching. Inf. Comput., 181(1):57–74, 2003. doi:10.1016/S0890-5401(02)00035-4.
- [2] Brenda S. Baker. Parameterized Pattern Matching: Algorithms and Applications. J. Comput. Syst. Sci., 52(1):28–42, 1996. doi:10.1006/JCSS.1996.0003.
- [3] Hideo Bannai, Tomohiro I, Shunsuke Inenaga, Yuto Nakashima, Masayuki Takeda, and Kazuya Tsuruta. The "Runs" Theorem. SIAM J. Comput., 46(5):1501–1514, 2017. doi:10.1137/15M1011032.
- [4] Maxime Crochemore and Wojciech Rytter. Squares, Cubes, and Time-Space Efficient String Searching. Algorithmica, 13(5):405–425, 1995. doi:10.1007/BF01190846.
- [5] Maxime Crochemore and Wojciech Rytter. Jewels of stringology: text algorithms. World Scientific, 2002.
- [6] Jonas Ellert and Johannes Fischer. Linear Time Runs Over General Ordered Alphabets. In 48th International Colloquium on Automata, Languages, and Programming, ICALP 2021, Glasgow, Scotland (Virtual Conference), July 12-16, 2021, pages 63:1–63:16. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2021. doi:10.4230/LIPIcs.ICALP.2021.63.
- [7] Michael Fredman and Dan Willard. Blasting through the information theoretic barrier with fusion trees. In ACM Symposium on Theory of Computing, pages 1–7, 1990. doi:10.1145/100216.100217.
- [8] Garance Gourdel, Tomasz Kociumaka, Jakub Radoszewski, Wojciech Rytter, Arseny M. Shur, and Tomasz Walen. String periods in the order-preserving model. Inf. Comput., 270, 2020. doi:10.1016/J.IC.2019.104463.
- [9] Diptarama Hendrian. Generalized Dictionary Matching Under Substring Consistent Equivalence Relations. In WALCOM: Algorithms and Computation (WALCOM 2020), volume 12049 of Lecture Notes in Computer Science, pages 120–132. Springer, 2020. doi:10.1007/978-3-030-39881-1_11.
- [10] Tomohiro I, Shunsuke Inenaga, and Masayuki Takeda. Palindrome pattern matching. Theor. Comput. Sci., 483:162–170, 2013. doi:10.1016/J.TCS.2012.01.047.
- [11] Jinil Kim, Peter Eades, Rudolf Fleischer, Seok-Hee Hong, Costas S. Iliopoulos, Kunsoo Park, Simon J. Puglisi, and Takeshi Tokuyama. Order-preserving matching. Theor. Comput. Sci., 525:68–79, 2014. doi:10.1016/J.TCS.2013.10.006.
- [12] Donald E. Knuth, James H. Morris Jr., and Vaughan R. Pratt. Fast Pattern Matching in Strings. SIAM J. Comput., 6(2):323–350, 1977. doi:10.1137/0206024.
- [13] Roman M. Kolpakov and Gregory Kucherov. Finding Maximal Repetitions in a Word in Linear Time. In 40th Annual Symposium on Foundations of Computer Science, FOCS 1999, New York, NY, USA, October 17-18, 1999, pages 596–604. IEEE Computer Society, 1999. doi:10.1109/SFFCS.1999.814634.
- [14] Xingyu Liao, Wufei Zhu, Juexiao Zhou, Haoyang Li, Xiaopeng Xu, Bin Zhang, and Xin Gao. Repetitive DNA sequence detection and its role in the human genome. Communications biology, 6(1):954, 2023. doi:10.1038/s42003-023-05322-y.
- [15] Yoshiaki Matsuoka, Takahiro Aoki, Shunsuke Inenaga, Hideo Bannai, and Masayuki Takeda. Generalized pattern matching and periodicity under substring consistent equivalence relations. Theor. Comput. Sci., 656:225–233, 2016. doi:10.1016/J.TCS.2016.02.017.
- [16] Peter Bro Miltersen. Error Correcting Codes, Perfect Hashing Circuits, and Deterministic Dynamic Dictionaries. In Proceedings of the Ninth Annual ACM-SIAM Symposium on Discrete Algorithms (SODA), pages 556–563. SIAM, 1998. URL: http://dl.acm.org/citation.cfm?id=314613.314845.
- [17] Shinya Nagashita and Tomohiro I. PalFM-Index: FM-Index for Palindrome Pattern Matching. In 34th Annual Symposium on Combinatorial Pattern Matching (CPM 2023), volume 259 of LIPIcs, pages 23:1–23:15. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2023. doi:10.4230/LIPIcs.CPM.2023.23.
- [18] Sung Gwan Park, Amihood Amir, Gad M. Landau, and Kunsoo Park. Cartesian Tree Matching and Indexing. In 30th Annual Symposium on Combinatorial Pattern Matching (CPM 2019), volume 128 of LIPIcs, pages 16:1–16:14. Schloss Dagstuhl – Leibniz-Zentrum für Informatik, 2019. doi:10.4230/LIPIcs.CPM.2019.16.
- [19] Mihai Pătraşcu and Mikkel Thorup. Dynamic Integer Sets with Optimal Rank, Select, and Predecessor Search. In 55th IEEE Annual Symposium on Foundations of Computer Science, FOCS 2014, Philadelphia, PA, USA, October 18-21, 2014, pages 166–175. IEEE Computer Society, 2014. doi:10.1109/FOCS.2014.26.
- [20] Jouni Paulus and Anssi Klapuri. Music structure analysis by finding repeated parts. In Proceedings of the 1st ACM Workshop on Audio and Music Computing Multimedia, pages 59–68. Association for Computing Machinery, 2006. doi:10.1145/1178723.1178733.
- [21] Jouni Paulus, Meinard Müller, and Anssi Klapuri. State of the Art Report: Audio-Based Music Structure Analysis. In International Society for Music Information Retrieval Conference (ISMIR 2010), pages 625–636. ISMIR, 2010. URL: http://ismir2010.ismir.net/proceedings/ismir2010-107.pdf.
- [22] Siwoo Song, Geonmo Gu, Cheol Ryu, Simone Faro, Thierry Lecroq, and Kunsoo Park. Fast algorithms for single and multiple pattern Cartesian tree matching. Theor. Comput. Sci., 849:47–63, 2021. doi:10.1016/J.TCS.2020.10.009.
