Outline
- Problem
- Algorithm
- Complexity Analysis
- Code
- Example Problems
- Problem 1
Hello, in this blog I'll share a funny way to construct a suffix tree in
Problem
A suffix tree of a string
I am going to share a simple and practically useless way of building it in a worse time complexity,
Algorithm
Notation
- When I refer to "suffix
" ahead, I mean the suffix . -
is the leaf node corresponding to suffix in the final suffix tree.
Initially, we start with an empty tree (with a virtual root node), and a set
It's easy to see that the paths from the root node to
Our algorithm will essentially do the following:
- Find
. - Split apart
into disjoint subsets (each subset will have suffixes whose leaves lie in the subtree of a unique child node of ). - Solve the problem recursively for each subset, and add an edge in the suffix tree from
to for every .
Now, we define a recursive function
Definitions
-
: a set of suffixes (represented by starting indices) -
: "leader" element (possibly undefined, in which case it will be "null") : depth of (the internal node of the parent call).-
: sorted list of integers (possibly undefined).
In each call,
- If the "Leader" element
is undefined:- Set
to a random element of . - For every suffix
, find , the longest common prefix of the suffixes and . This can be done in using binary search + hashing. We store in a sorted manner.
- Set
- Let
be the minimum value in . It's easy to see that the internal node created from splitting will occur at depth . We create , and add an edge corresponding to the substring from to . - Now, we delete all suffixes
, from (and their corresponding elements from ), and group them into disjoint subsets based on the character for suffix (basically the next character after the internal node). - We call
for every newly created subset , and also call for the modified subset .
Note: There might be some off-by-one errors.
Complexity Analysis
Consider the following problem:
We have
singleton sets, and are given some set merge operations. When merging sets and , we merge to with probability and to with the probability .
The above problem is computationally equivalent to Randomized Quicksort, which has an expected time complexity of
It's not difficult to see that our split operations are simply the operations that will occur in the above problem in a reversed manner (Formally, we can define a bijective relationship between the two sets of operations, such that related sets of operations will occur with the same probability) . Therefore, the time taken by all the split operations is
However, every time we perform a split operation (merge in reverse), we also compute
Code
My implementation can be found here.
Example Problems
Problem 1
You are given a tree on
nodes. You also have a set containing all nodes, . You have to process the following queries online:
- "
" : Remove the nodes from the set whose maximum element is , and create a new set with these elements (it is guaranteed that there exists some set with maximum element and ). - "
" : Let the set whose maximum element is be . Find some node .