Kasai’s Algorithm is an algorithm that computes for a string of length , where
where denotes the starting index of the -th lexicographically smallest suffix of , in time and space.
Algorithm 0
- Apply the Manber-Myers Algorithm to find .
- Apply the definition to find .
This algorithm solves the problem in time and space.
std::vector<int> kasai(int n, const std::string &s) {
auto sa = manber_myers(n, s);
std::vector h(n - 1, 0);
for (int i = 0; i < n - 1; i++) {
while (sa[i] + h[i] < n && sa[i + 1] + h[i] < n && s[sa[i] + h[i]] == s[sa[i + 1] + h[i]]) {
h[i]++;
}
}
return h;
}Algorithm 1
Lemma
Let denote the lexicographical rank of among all the suffixes of , and let , then
Proof
Let .
If ,
Based on Algorithm 0, applying the lemma to find a lower bound for yields an algorithm that solves the problem in time and space.
std::vector<int> kasai(int n, const std::string &s) {
auto sa = manber_myers(n, s);
std::vector<int> rk(n);
for (int i = 0; i < n; i++) {
rk[sa[i]] = i;
}
std::vector<int> h(n - 1);
for (int i = 0, j = 0; i < n; i++) {
if (rk[i] == n - 1) {
continue;
}
j -= j > 0;
while (i + j < n && sa[rk[i] + 1] + j < n && s[i + j] == s[sa[rk[i] + 1] + j]) {
j++;
}
h[rk[i]] = j;
}
return h;
}Proof
The total number of executions of
j++is