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

  1. Apply the Manber-Myers Algorithm to find .
  2. 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

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;
}