V

Algorithm Visualizer

ZHEN
Share on WeiboShare on XGitHub repositoryAuthor website
Learning ToolsAlgorithm Complexity ReferenceAlgorithm Learning Paths
Data StructuresArrayLinked ListStackQueue and DequeBinary Search TreeBinary HeapHash TableGraphTrieDisjoint Set UnionLRU CacheSkip ListSegment TreeB+ TreeBloom FilterFenwick Tree
SortingBubble SortCocktail Shaker SortBitonic SortSelection SortInsertion SortBinary Insertion SortShell SortMerge SortTop-Down Merge SortQuick SortThree-Way Quick SortDual-Pivot Quick SortHeap SortCounting SortRadix SortBucket Sort
Graph AlgorithmsDijkstra's Shortest PathKruskal's Minimum Spanning TreePrim's Minimum Spanning TreeBellman-Ford Shortest PathsTopological SortFloyd-WarshallStrongly Connected Components2-SATMaximum FlowBipartite MatchingLowest Common AncestorEulerian Path
Dynamic ProgrammingEdit Distance0/1 KnapsackUnbounded KnapsackLongest Common SubsequenceLongest Increasing SubsequenceCoin ChangeStone MergingTraveling Salesperson DPTree Dynamic ProgrammingDigit DPRerooting DP
Backtracking and SearchN-QueensSubsetsPermutationsCombination SumMaze Solving with DFSNumber of IslandsWord SearchSudoku SolverA* Search
StringsKMP String MatchingRabin-Karp String MatchingBoyer-Moore String MatchingManacher's Longest Palindromic SubstringSuffix ArrayLCP ArrayAho-Corasick AutomatonZ Function
Math and Number TheorySieve of EratosthenesLinear SieveEuclidean AlgorithmBinary ExponentiationExtended Euclidean AlgorithmChinese Remainder TheoremEuler's Totient FunctionMiller-Rabin Primality TestFast Fourier TransformPollard's Rho Factorization
Computational GeometryConvex HullRotating CalipersClosest Pair of PointsLine Segment IntersectionBentley-Ottmann Sweep Line
SearchingBinary SearchLower and Upper BoundSearch in a Rotated Sorted ArrayBinary Search on the AnswerTernary Search

LCP Array

Use inverse suffix ranks and Kasai reuse to compute adjacent longest common prefixes in linear time.

Core idea

Kasai's algorithm visits suffixes in text order. If one suffix shares h characters with its suffix-array predecessor, the next text suffix can reuse at least h minus one before extending comparisons.

Read the visualization

The suffix-array rank selects the comparison neighbor. A highlighted prefix shows reused characters, then grows only while new characters match.

b0
a1
n2
a3
n4
a5
LCP of adjacent suffixes (Kasai)
StartSuffixrankLCP↑
5a0-
3ana1
1anana2
0banana3
4na4
2nana5

Build inverse suffix ranks and initialize the reusable prefix length to zero.

1function kasai(s: string, sa: number[]): number[] {
2 const n = s.length;
3 const rank = new Array(n);
4 for (let i = 0; i < n; i++) rank[sa[i]] = i; // sa init
5 const lcp = new Array(n).fill(0);
6 let h = 0;
7 for (let i = 0; i < n; i++) { // init index i init
8 if (rank[i] > 0) {
9 const j = sa[rank[i] - 1]; // fill predecessor suffix
10 while (i + h < n && j + h < n && s[i + h] === s[j + h]) h++; // h fill
11 lcp[rank[i]] = h; // fill LCP
12 if (h > 0) h--; // fill character: h fill 1
13 } else {
14 h = 0; // rank 0: skip predecessor
15 }
16 }
17 return lcp;
18}
original stringbanana
sa[5,3,1,0,4,2]
current suffix i-
h0
1 / 8

Complexity and tradeoffs

Time: O(n). Space: O(n). The reused prefix length decreases by at most one per text position, bounding total comparisons.

Invariant: The carried match length is a valid lower bound for the next suffix comparison and decreases by at most one between text positions.

Where it fits

Together with a suffix array, LCP values reveal repeated substrings and support range-minimum queries for arbitrary suffix-prefix lengths.