DrawCode Algorithm Visualizer • String • Hard

Suffix Array

Tags: String, Suffix Array, Ranking, Substring

1. One-Liner

A suffix array SA is the list of indices sorting all suffixes of S lexicographically; with LCP it powers fast substring and repetition queries.


2. The Problem It Solves

Answer “how do suffixes relate?” in sorted order — used for substring search, longest repeated substring, number of distinct substrings, and BWT-adjacent structures.


3. The Core Idea

Doubling: sort suffixes by their first 2^k characters using ranks from the previous 2^{k-1} sort — like radix sort on pairs (rank[i], rank[i+2^{k-1}]).


4. How It Works (Table)

StepWhat Happens
1Pad with sentinel $ smaller than alphabet if needed.
2Initial ranks = character codes.
3Repeat: sort SA by pairs (rank[i], rank[i+k]) until ranks unique.
4Result SA is lexicographic suffix order.

5. Dry Run Example

"aba

quot; → suffixes aba$, ba$, a$, $ → sorted order indices give SA.


6. Key Properties

PropertyValue
BuildO(n log n) typical (doubling); O(n) advanced (SA-IS)
SpaceO(n)
With LCPEnables linear-space substring stats

7. Where It Is Used

DomainUse
BioinformaticsFM-index / BWT pipelines
CompressionBurrows–Wheeler transform
Text indexingCompetitive programming, research

8. Interview Tips

Know doubling intuition; mention LCP with Kasai as follow-up. For interviews, O(n log² n) acceptable if clean.


9. Comparison with Other Algorithms

StructureTradeoff
Suffix trie/treeMore memory, easier incremental
Suffix arrayCompact, needs LCP for some queries

10. Complexity

MetricValue
Doubling buildO(n log n) time, O(n) space
SA-ISO(n) time (advanced)

Implementation Example (PYTHON)

def suffix_array(s):
    s = s + '
n = len(s) sa = list(range(n)) rank = [ord(c) for c in s] tmp = [0] * n k = 1 while k < n: sa.sort(key=lambda i: (rank[i], rank[i + k] if i + k < n else -1)) tmp[sa[0]] = 0 for i in range(1, n): a, b = sa[i - 1], sa[i] prev = (rank[a], rank[a + k] if a + k < n else -1) cur = (rank[b], rank[b + k] if b + k < n else -1) tmp[b] = tmp[a] + (prev != cur) rank = tmp[:] if rank[sa[-1]] == n - 1: break k <<= 1 return sa

Interactive Visualizer Workspace

Explore step-by-step interactive animations, memory state tracking, and live multi-language execution in DrawCode.

Launch Interactive Visualizer