kasai’s Algorithm for Construction of LCP array from Suffix Array
Last Updated :
23 Jul, 2025
Background Suffix Array : A suffix array is a sorted array of all suffixes of a given string.
Let the given string be "banana".
0 banana 5 a
1 anana Sort the Suffixes 3 ana
2 nana ----------------> 1 anana
3 ana alphabetically 0 banana
4 na 4 na
5 a 2 nana
The suffix array for "banana" :
suffix[] = {5, 3, 1, 0, 4, 2}
We have discussed Suffix Array and it O(nLogn) construction .
Once Suffix array is built, we can use it to efficiently search a pattern in a text. For example, we can use Binary Search to find a pattern (Complete code for the same is discussed here)
LCP Array
The Binary Search based solution discussed here takes O(m*Logn) time where m is length of the pattern to be searched and n is length of the text. With the help of LCP array, we can search a pattern in O(m + Log n) time. For example, if our task is to search "ana" in "banana", m = 3, n = 5.
LCP Array is an array of size n (like Suffix Array). A value lcp[i] indicates length of the longest common prefix of the suffixes indexed by suffix[i] and suffix[i+1]. suffix[n-1] is not defined as there is no suffix after it.
txt[0..n-1] = "banana"
suffix[] = {5, 3, 1, 0, 4, 2|
lcp[] = {1, 3, 0, 0, 2, 0}
Suffixes represented by suffix array in order are:
{"a", "ana", "anana", "banana", "na", "nana"}
lcp[0] = Longest Common Prefix of "a" and "ana" = 1
lcp[1] = Longest Common Prefix of "ana" and "anana" = 3
lcp[2] = Longest Common Prefix of "anana" and "banana" = 0
lcp[3] = Longest Common Prefix of "banana" and "na" = 0
lcp[4] = Longest Common Prefix of "na" and "nana" = 2
lcp[5] = Longest Common Prefix of "nana" and None = 0
How to construct LCP array?
LCP array construction is done two ways:
1) Compute the LCP array as a byproduct to the suffix array (Manber & Myers Algorithm)
2) Use an already constructed suffix array in order to compute the LCP values. (Kasai Algorithm).
There exist algorithms that can construct Suffix Array in O(n) time and therefore we can always construct LCP array in O(n) time. But in the below implementation, a O(n Log n) algorithm is discussed.
kasai’s Algorithm
In this article, kasai’s Algorithm is discussed. The algorithm constructs LCP array from suffix array and input text in O(n) time. The idea is based on below fact:
Let lcp of suffix beginning at txt[i[ be k. If k is greater than 0, then lcp for suffix beginning at txt[i+1] will be at-least k-1. The reason is, relative order of characters remain same. If we delete the first character from both suffixes, we know that at least k characters will match. For example for substring "ana", lcp is 3, so for string "na" lcp will be at-least 2. Refer this for proof.
Below is the C++ implementation of Kasai's algorithm.
C++
// C++ program for building LCP array for given text
#include <bits/stdc++.h>
using namespace std;
// Structure to store information of a suffix
struct suffix
{
int index; // To store original index
int rank[2]; // To store ranks and next rank pair
};
// A comparison function used by sort() to compare two suffixes
// Compares two pairs, returns 1 if first pair is smaller
int cmp(struct suffix a, struct suffix b)
{
return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0):
(a.rank[0] < b.rank[0] ?1: 0);
}
// This is the main function that takes a string 'txt' of size n as an
// argument, builds and return the suffix array for the given string
vector<int> buildSuffixArray(string txt, int n)
{
// A structure to store suffixes and their indexes
struct suffix suffixes[n];
// Store suffixes and their indexes in an array of structures.
// The structure is needed to sort the suffixes alphabetically
// and maintain their old indexes while sorting
for (int i = 0; i < n; i++)
{
suffixes[i].index = i;
suffixes[i].rank[0] = txt[i] - 'a';
suffixes[i].rank[1] = ((i+1) < n)? (txt[i + 1] - 'a'): -1;
}
// Sort the suffixes using the comparison function
// defined above.
sort(suffixes, suffixes+n, cmp);
// At his point, all suffixes are sorted according to first
// 2 characters. Let us sort suffixes according to first 4
// characters, then first 8 and so on
int ind[n]; // This array is needed to get the index in suffixes[]
// from original index. This mapping is needed to get
// next suffix.
for (int k = 4; k < 2*n; k = k*2)
{
// Assigning rank and index values to first suffix
int rank = 0;
int prev_rank = suffixes[0].rank[0];
suffixes[0].rank[0] = rank;
ind[suffixes[0].index] = 0;
// Assigning rank to suffixes
for (int i = 1; i < n; i++)
{
// If first rank and next ranks are same as that of previous
// suffix in array, assign the same new rank to this suffix
if (suffixes[i].rank[0] == prev_rank &&
suffixes[i].rank[1] == suffixes[i-1].rank[1])
{
prev_rank = suffixes[i].rank[0];
suffixes[i].rank[0] = rank;
}
else // Otherwise increment rank and assign
{
prev_rank = suffixes[i].rank[0];
suffixes[i].rank[0] = ++rank;
}
ind[suffixes[i].index] = i;
}
// Assign next rank to every suffix
for (int i = 0; i < n; i++)
{
int nextindex = suffixes[i].index + k/2;
suffixes[i].rank[1] = (nextindex < n)?
suffixes[ind[nextindex]].rank[0]: -1;
}
// Sort the suffixes according to first k characters
sort(suffixes, suffixes+n, cmp);
}
// Store indexes of all sorted suffixes in the suffix array
vector<int>suffixArr;
for (int i = 0; i < n; i++)
suffixArr.push_back(suffixes[i].index);
// Return the suffix array
return suffixArr;
}
/* To construct and return LCP */
vector<int> kasai(string txt, vector<int> suffixArr)
{
int n = suffixArr.size();
// To store LCP array
vector<int> lcp(n, 0);
// An auxiliary array to store inverse of suffix array
// elements. For example if suffixArr[0] is 5, the
// invSuff[5] would store 0. This is used to get next
// suffix string from suffix array.
vector<int> invSuff(n, 0);
// Fill values in invSuff[]
for (int i=0; i < n; i++)
invSuff[suffixArr[i]] = i;
// Initialize length of previous LCP
int k = 0;
// Process all suffixes one by one starting from
// first suffix in txt[]
for (int i=0; i<n; i++)
{
/* If the current suffix is at n-1, then we don’t
have next substring to consider. So lcp is not
defined for this substring, we put zero. */
if (invSuff[i] == n-1)
{
k = 0;
continue;
}
/* j contains index of the next substring to
be considered to compare with the present
substring, i.e., next string in suffix array */
int j = suffixArr[invSuff[i]+1];
// Directly start matching from k'th index as
// at-least k-1 characters will match
while (i+k<n && j+k<n && txt[i+k]==txt[j+k])
k++;
lcp[invSuff[i]] = k; // lcp for the present suffix.
// Deleting the starting character from the string.
if (k>0)
k--;
}
// return the constructed lcp array
return lcp;
}
// Utility function to print an array
void printArr(vector<int>arr, int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver program
int main()
{
string str = "banana";
vector<int>suffixArr = buildSuffixArray(str, str.length());
int n = suffixArr.size();
cout << "Suffix Array : \n";
printArr(suffixArr, n);
vector<int>lcp = kasai(str, suffixArr);
cout << "\nLCP Array : \n";
printArr(lcp, n);
return 0;
}
Java
import java.util.Arrays;
import java.util.Vector;
// Structure to store information of a suffix
class Suffix {
int index; // To store original index
int[] rank = new int[2]; // To store ranks and next rank pair
}
public class SuffixArray {
// A comparison function used by Arrays.sort() to compare two suffixes
// Compares two pairs, returns 1 if the first pair is smaller
static int cmp(Suffix a, Suffix b) {
return (a.rank[0] == b.rank[0]) ? Integer.compare(a.rank[1], b.rank[1]) : Integer.compare(a.rank[0], b.rank[0]);
}
// This is the main function that takes a string 'txt' of size n as an
// argument, builds and returns the suffix array for the given string
static Vector<Integer> buildSuffixArray(String txt, int n) {
// A structure to store suffixes and their indexes
Suffix[] suffixes = new Suffix[n];
// Store suffixes and their indexes in an array of structures.
// The structure is needed to sort the suffixes alphabetically
// and maintain their old indexes while sorting
for (int i = 0; i < n; i++) {
suffixes[i] = new Suffix();
suffixes[i].index = i;
suffixes[i].rank[0] = txt.charAt(i) - 'a';
suffixes[i].rank[1] = (i + 1) < n ? (txt.charAt(i + 1) - 'a') : -1;
}
// Sort the suffixes using the comparison function
// defined above.
Arrays.sort(suffixes, SuffixArray::cmp);
// At this point, all suffixes are sorted according to the first
// 2 characters. Let us sort suffixes according to first 4
// characters, then first 8 and so on
int[] ind = new int[n]; // This array is needed to get the index in suffixes[]
// from the original index. This mapping is needed to get
// the next suffix.
for (int k = 4; k < 2 * n; k = k * 2) {
// Assigning rank and index values to the first suffix
int rank = 0;
int prev_rank = suffixes[0].rank[0];
suffixes[0].rank[0] = rank;
ind[suffixes[0].index] = 0;
// Assigning rank to suffixes
for (int i = 1; i < n; i++) {
// If the first rank and next ranks are the same as that of the previous
// suffix in the array, assign the same new rank to this suffix
if (suffixes[i].rank[0] == prev_rank &&
suffixes[i].rank[1] == suffixes[i - 1].rank[1]) {
prev_rank = suffixes[i].rank[0];
suffixes[i].rank[0] = rank;
} else { // Otherwise increment rank and assign
prev_rank = suffixes[i].rank[0];
suffixes[i].rank[0] = ++rank;
}
ind[suffixes[i].index] = i;
}
// Assign next rank to every suffix
for (int i = 0; i < n; i++) {
int nextindex = suffixes[i].index + k / 2;
suffixes[i].rank[1] = (nextindex < n) ?
suffixes[ind[nextindex]].rank[0] : -1;
}
// Sort the suffixes according to the first k characters
Arrays.sort(suffixes, SuffixArray::cmp);
}
// Store indexes of all sorted suffixes in the suffix array
Vector<Integer> suffixArr = new Vector<>();
for (int i = 0; i < n; i++)
suffixArr.add(suffixes[i].index);
// Return the suffix array
return suffixArr;
}
/* To construct and return LCP */
static Vector<Integer> kasai(String txt, Vector<Integer> suffixArr) {
int n = suffixArr.size();
// To store LCP array
int temp[]=new int[n];
Vector<Integer> lcp = new Vector<>(n);
// An auxiliary array to store the inverse of the suffix array
// elements. For example, if suffixArr[0] is 5, the
// invSuff[5] would store 0. This is used to get the next
// suffix string from the suffix array.
int[] invSuff = new int[n];
// Fill values in invSuff[]
for (int i = 0; i < n; i++)
invSuff[suffixArr.get(i)] = i;
// Initialize the length of the previous LCP
int k = 0;
// Process all suffixes one by one starting from
// the first suffix in txt[]
for (int i = 0; i < n; i++) {
/* If the current suffix is at n-1, then we don’t
have the next substring to consider. So lcp is not
defined for this substring, we put zero. */
if (invSuff[i] == n - 1) {
k = 0;
continue;
}
/* j contains the index of the next substring to
be considered to compare with the present
substring, i.e., the next string in the suffix array */
int j = suffixArr.get(invSuff[i] + 1);
// Directly start matching from k'th index as
// at least k-1 characters will match
while (i + k < n && j + k < n && txt.charAt(i + k) == txt.charAt(j + k))
k++;
temp[invSuff[i]]=k;// lcp for the present suffix.
// Deleting the starting character from the string.
if (k > 0)
k--;
}
for(int i=0;i<n;i++) {
lcp.add(temp[i]);
}
// return the constructed lcp array
return lcp;
}
// Utility function to print an array
static void printArr(Vector<Integer> arr,int n) {
for (Integer value : arr)
System.out.print(value + " ");
System.out.println();
}
// Driver program
public static void main(String[] args) {
String str = "banana";
Vector<Integer> suffixArr = buildSuffixArray(str, str.length());
int n = suffixArr.size();
System.out.println("Suffix Array : ");
printArr(suffixArr, n);
Vector<Integer> lcp = kasai(str, suffixArr);
System.out.println("\nLCP Array : ");
printArr(lcp, n);
}
}
Python
class Suffix:
def __init__(self):
self.index = 0
self.rank = [0, 0]
def buildSuffixArray(txt, n):
suffixes = [Suffix() for _ in range(n)]
for i in range(n):
suffixes[i].index = i
suffixes[i].rank[0] = ord(txt[i]) - ord('a')
suffixes[i].rank[1] = ord(txt[i + 1]) - ord('a') if i + 1 < n else -1
suffixes.sort(key=lambda x: (x.rank[0], x.rank[1]))
ind = [0] * n
for k in range(4, 2 * n, k * 2) if 'k' in locals() and k > 0 else range(4, 2 * n, 1):
rank = 0
prev_rank = suffixes[0].rank[0]
suffixes[0].rank[0] = rank
ind[suffixes[0].index] = 0
for i in range(1, n):
if suffixes[i].rank[0] == prev_rank and suffixes[i].rank[1] == suffixes[i - 1].rank[1]:
prev_rank = suffixes[i].rank[0]
suffixes[i].rank[0] = rank
else:
prev_rank = suffixes[i].rank[0]
suffixes[i].rank[0] = rank + 1
ind[suffixes[i].index] = i
for i in range(n):
nextindex = suffixes[i].index + k // 2
suffixes[i].rank[1] = suffixes[ind[nextindex]].rank[0] if nextindex < n else -1
suffixes.sort(key=lambda x: (x.rank[0], x.rank[1]))
suffixArr = [suffix.index for suffix in suffixes]
return suffixArr
def kasai(txt, suffixArr):
n = len(suffixArr)
lcp = [0] * n
invSuff = [0] * n
for i in range(n):
invSuff[suffixArr[i]] = i
k = 0
for i in range(n):
if invSuff[i] == n - 1:
k = 0
continue
j = suffixArr[invSuff[i] + 1]
while i + k < n and j + k < n and txt[i + k] == txt[j + k]:
k += 1
lcp[invSuff[i]] = k
if k > 0:
k -= 1
return lcp
# Utility function to print an array
def printArr(arr):
print(" ".join(map(str, arr)))
# Driver program
if __name__ == "__main__":
input_str = "banana"
suffixArr = buildSuffixArray(input_str, len(input_str))
n = len(suffixArr)
print("Suffix Array:")
printArr(suffixArr)
lcp = kasai(input_str, suffixArr)
print("\nLCP Array:")
printArr(lcp)
C#
using System;
using System.Collections.Generic;
// Structure to store information of a suffix
public struct Suffix
{
public int Index; // To store original index
public int[] Rank; // To store ranks and next rank pair
}
public class SuffixArray {
// A comparison function used by Sort() to compare two
// suffixes
// Compares two pairs, returns -1 if the first pair is
// smaller
private static int CompareSuffixes(Suffix a, Suffix b)
{
return (a.Rank[0] == b.Rank[0])
? (a.Rank[1] < b.Rank[1] ? -1 : 1)
: (a.Rank[0] < b.Rank[0] ? -1 : 1);
}
// This is the main function that takes a string 'txt'
// of size n as an argument, builds and returns the
// suffix array for the given string
public static List<int> BuildSuffixArray(string txt,
int n)
{
// A structure to store suffixes and their indexes
Suffix[] suffixes = new Suffix[n];
// Store suffixes and their indexes in an array of
// structures. The structure is needed to sort the
// suffixes alphabetically and maintain their old
// indexes while sorting
for (int i = 0; i < n; i++) {
suffixes[i].Index = i;
suffixes[i].Rank = new int[2] {
txt[i] - 'a',
(i + 1) < n ? txt[i + 1] - 'a' : -1
};
}
// Sort the suffixes using the comparison function
// defined above.
Array.Sort(suffixes, CompareSuffixes);
// At this point, all suffixes are sorted according
// to the first 2 characters. Let us sort suffixes
// according to the first 4 characters, then first 8
// and so on
int[] ind
= new int[n]; // This array is needed to get the
// index in suffixes[] from the
// original index. This mapping is
// needed to get the next suffix.
for (int k = 4; k < 2 * n; k = k * 2) {
// Assigning rank and index values to the first
// suffix
int rank = 0;
int prevRank = suffixes[0].Rank[0];
suffixes[0].Rank[0] = rank;
ind[suffixes[0].Index] = 0;
// Assigning rank to suffixes
for (int i = 1; i < n; i++) {
// If the first rank and next ranks are the
// same as that of the previous suffix in
// the array, assign the same new rank to
// this suffix
if (suffixes[i].Rank[0] == prevRank
&& suffixes[i].Rank[1]
== suffixes[i - 1].Rank[1]) {
prevRank = suffixes[i].Rank[0];
suffixes[i].Rank[0] = rank;
}
else // Otherwise increment rank and assign
{
prevRank = suffixes[i].Rank[0];
suffixes[i].Rank[0] = ++rank;
}
ind[suffixes[i].Index] = i;
}
// Assign the next rank to every suffix
for (int i = 0; i < n; i++) {
int nextIndex = suffixes[i].Index + k / 2;
suffixes[i].Rank[1]
= (nextIndex < n)
? suffixes[ind[nextIndex]].Rank[0]
: -1;
}
// Sort the suffixes according to the first k
// characters
Array.Sort(suffixes, CompareSuffixes);
}
// Store indexes of all sorted suffixes in the
// suffix array
List<int> suffixArr = new List<int>();
for (int i = 0; i < n; i++)
suffixArr.Add(suffixes[i].Index);
// Return the suffix array
return suffixArr;
}
/* To construct and return LCP */
public static List<int> Kasai(string txt,
List<int> suffixArr)
{
int n = suffixArr.Count;
// To store the LCP array
List<int> lcp = new List<int>(new int[n]);
// An auxiliary array to store the inverse of suffix
// array elements. For example, if suffixArr[0] is
// 5, the invSuff[5] would store 0. This is used to
// get the next suffix string from the suffix array.
int[] invSuff = new int[n];
// Fill values in invSuff[]
for (int i = 0; i < n; i++)
invSuff[suffixArr[i]] = i;
// Initialize the length of the previous LCP
int k = 0;
// Process all suffixes one by one starting from
// the first suffix in txt[]
for (int i = 0; i < n; i++) {
/* If the current suffix is at n-1, then we
don’t have the next substring to consider. So
LCP is not
defined for this substring, we put zero. */
if (invSuff[i] == n - 1) {
k = 0;
continue;
}
/* j contains the index of the next substring to
be considered to compare with the present
substring, i.e., the next string in the
suffix array */
int j = suffixArr[invSuff[i] + 1];
// Directly start matching from the k'th index
// as at least k-1 characters will match
while (i + k < n && j + k < n
&& txt[i + k] == txt[j + k])
k++;
lcp[invSuff[i]]
= k; // LCP for the present suffix.
// Deleting the starting character from the
// string.
if (k > 0)
k--;
}
// Return the constructed LCP array
return lcp;
}
// Utility function to print an array
public static void PrintArr(List<int> arr, int n)
{
for (int i = 0; i < n; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
// Driver program
public static void Main()
{
string str = "banana";
List<int> suffixArr
= BuildSuffixArray(str, str.Length);
int n = suffixArr.Count;
Console.WriteLine("Suffix Array :");
PrintArr(suffixArr, n);
List<int> lcp = Kasai(str, suffixArr);
Console.WriteLine("\nLCP Array :");
PrintArr(lcp, n);
}
}
// This code is contributed by shivamgupta0987654321
JavaScript
// Define a class for storing suffix information
class Suffix {
constructor(index, rank1, rank2) {
this.index = index; // Store the original index
this.rank = [rank1, rank2]; // Store ranks and next rank pair
}
}
// Comparison function used for sorting suffixes
function cmp(a, b) {
// Compare ranks of suffixes
return (a.rank[0] === b.rank[0]) ? (a.rank[1] < b.rank[1] ? -1 : 1) :
(a.rank[0] < b.rank[0] ? -1 : 1);
}
// Function to build the suffix array of a given text
function buildSuffixArray(txt) {
const n = txt.length;
const suffixes = [];
// Generate suffixes and their ranks
for (let i = 0; i < n; i++) {
suffixes[i] = new Suffix(i, txt.charCodeAt(i) - 'a'.charCodeAt(0),
((i + 1) < n) ? txt.charCodeAt(i + 1) - 'a'.charCodeAt(0) : -1);
}
// Sort the generated suffixes using the comparison function
suffixes.sort(cmp);
// Array to map the original index of suffixes after sorting
const ind = new Array(n).fill(0);
// Loop for sorting suffixes based on multiple characters
for (let k = 4; k < 2 * n; k *= 2) {
let rank = 0;
let prevRank = suffixes[0].rank[0];
suffixes[0].rank[0] = rank;
ind[suffixes[0].index] = 0;
for (let i = 1; i < n; i++) {
if (suffixes[i].rank[0] === prevRank &&
suffixes[i].rank[1] === suffixes[i - 1].rank[1]) {
prevRank = suffixes[i].rank[0];
suffixes[i].rank[0] = rank;
} else {
prevRank = suffixes[i].rank[0];
suffixes[i].rank[0] = ++rank;
}
ind[suffixes[i].index] = i;
}
for (let i = 0; i < n; i++) {
const nextIndex = suffixes[i].index + k / 2;
suffixes[i].rank[1] = (nextIndex < n) ?
suffixes[ind[nextIndex]].rank[0] : -1;
}
suffixes.sort(cmp);
}
// Create the suffix array from the sorted suffixes
const suffixArr = suffixes.map(suffix => suffix.index);
return suffixArr; // Return the suffix array
}
// Function to construct and return the LCP (Longest Common Prefix) array
function kasai(txt, suffixArr) {
const n = suffixArr.length;
const lcp = new Array(n).fill(0);
const invSuff = new Array(n).fill(0);
// Fill the inverse suffix array
for (let i = 0; i < n; i++)
invSuff[suffixArr[i]] = i;
let k = 0;
for (let i = 0; i < n; i++) {
if (invSuff[i] === n - 1) {
k = 0;
continue;
}
let j = suffixArr[invSuff[i] + 1];
// Compute LCP values using suffix array
while (i + k < n && j + k < n && txt[i + k] === txt[j + k])
k++;
lcp[invSuff[i]] = k; // Store the computed LCP
if (k > 0)
k--;
}
return lcp; // Return the constructed LCP array
}
// Utility function to print an array
function printArr(arr) {
console.log(arr.join(" ")); // Print array elements separated by spaces
}
const str = "banana"; // Input string
// Build the suffix array for the input string
const suffixArr = buildSuffixArray(str);
const n = suffixArr.length;
console.log("Suffix Array:");
printArr(suffixArr); // Print the generated suffix array
// Compute the LCP array using the suffix array
const lcp = kasai(str, suffixArr);
console.log("\nLCP Array:");
printArr(lcp); // Print the computed LCP array
Output:
Suffix Array :
5 3 1 0 4 2
LCP Array :
1 3 0 0 2 0
Illustration:
txt[] = "banana", suffix[] = {5, 3, 1, 0, 4, 2|
Suffix array represents
{"a", "ana", "anana", "banana", "na", "nana"}
Inverse Suffix Array would be
invSuff[] = {3, 2, 5, 1, 4, 0}
LCP values are evaluated in below order
We first compute LCP of first suffix in text which is "banana". We need next suffix in suffix array to compute LCP (Remember lcp[i] is defined as Longest Common Prefix of suffix[i] and suffix[i+1]). To find the next suffix in suffixArr[], we use SuffInv[]. The next suffix is "na". Since there is no common prefix between "banana" and "na", the value of LCP for "banana" is 0 and it is at index 3 in suffix array, so we fill lcp[3] as 0.
Next we compute LCP of second suffix which "anana". Next suffix of "anana" in suffix array is "banana". Since there is no common prefix, the value of LCP for "anana" is 0 and it is at index 2 in suffix array, so we fill lcp[2] as 0.
Next we compute LCP of third suffix which "nana". Since there is no next suffix, the value of LCP for "nana" is not defined. We fill lcp[5] as 0.
Next suffix in text is "ana". Next suffix of "ana" in suffix array is "anana". Since there is a common prefix of length 3, the value of LCP for "ana" is 3. We fill lcp[1] as 3.
Now we lcp for next suffix in text which is "na". This is where Kasai's algorithm uses the trick that LCP value must be at least 2 because previous LCP value was 3. Since there is no character after "na", final value of LCP is 2. We fill lcp[4] as 2.
Next suffix in text is "a". LCP value must be at least 1 because the previous value was 2. Since there is no character after "a", final value of LCP is 1. We fill lcp[0] as 1.
We will soon be discussing the implementation of search with the help of LCP array and how LCP array helps in reducing time complexity to O(m + Log n).
References:
http://web.stanford.edu/class/cs97si/suffix-array.pdf
http://www.mi.fu-berlin.de/wiki/pub/ABI/RnaSeqP4/suffix-array.pdf
https://codeforces.com/blog/entry/12796
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem