Skip to main content
Back to the DSA atlas
Strings Data structure Intermediate

Trie (Prefix Tree)

A tree-like data structure for efficient string storage and prefix-based retrieval. Essential for autocomplete, spell checking, and word search problems.

triestringtreeprefix

Interactive visualization

Use the controls to connect the idea to concrete operations before diving into the full write-up.

500ms
Idle Active Traversed Found / End of word Not found End-of-word node (thick border)

Family

Strings

Prefix-aware structures and text-centric search strategies.

Builds on

1 topic

Read these first if you want the surrounding context.

Unlocks

1 next topic

Use these follow-ups when you want to apply the current idea in a richer setting.

Learning paths

2

This topic appears in curated progressions so you can keep moving without guessing the next step.

Problem

Given a set of strings, you need to efficiently insert words, check if a word exists, and query all words that share a common prefix. Hash sets can check membership in O(1)O(1) amortized, but they can’t answer prefix queries without scanning every key. You need a structure where prefix lookups are first-class operations.

Intuition

A trie is a tree where each edge represents a single character and each path from root to a marked node spells out a word. Think of it like a phone book organized not alphabetically by full name, but character by character — you narrow down candidates with every letter you type. The root is the empty string. Every node implicitly represents the prefix formed by the path from the root to that node.

The key insight: words that share a prefix share the same path in the trie. “cat”, “car”, and “card” all traverse root → c → a, then diverge. This shared structure is what makes prefix operations efficient — you don’t re-examine characters you’ve already matched.

Algorithm

Insert(word):
    node ← root
    for char in word:
        if char not in node.children:
            node.children[char] ← new TrieNode()
        node ← node.children[char]
    node.isEnd ← true

Search(word):
    node ← root
    for char in word:
        if char not in node.children:
            return false
        node ← node.children[char]
    return node.isEnd

StartsWith(prefix):
    node ← root
    for char in prefix:
        if char not in node.children:
            return false
        node ← node.children[char]
    return true

Delete(word):
    // Recursive: walk to end, remove isEnd flag,
    // then backtrack deleting nodes with no children and no isEnd

Implementation details

A TrieNode holds a children mapping and an isEnd boolean. The two standard implementations for children:

ApproachLookupMemory per nodeWhen to use
Array of size 26O(1)O(1)Fixed 26 pointersLowercase English only, speed critical
Hash mapO(1)O(1) avgProportional to actual childrenUnicode, sparse alphabets, general purpose

The array approach wastes memory when most slots are null but gives cache-friendly constant-time access. The hash map approach is more flexible and memory-efficient for large or variable alphabets. In practice, for interview problems with lowercase English, use the array. For production systems, use a hash map.

You can also store a count field on each node to track how many words pass through it — useful for prefix counting without traversal.

Common patterns

Autocomplete. Walk the trie to the prefix node, then DFS from there to collect all words. This is O(P+K)O(P + K) where PP is prefix length and KK is the total characters in all matching words.

Word search on a board. Build a trie from the dictionary, then DFS on the grid while simultaneously walking the trie. The trie lets you prune branches early — if no word starts with the current path, stop. This is the standard approach for Leetcode 212.

Longest common prefix. Insert all strings, then walk from the root following only-child nodes until you hit a fork or an end-of-word marker. The depth at that point is your answer.

Counting distinct substrings. Insert all suffixes of a string into a trie. The number of nodes (excluding root) equals the number of distinct substrings.

When to use Trie vs other structures

StructureMembershipPrefix queryOrdered iterationSpace
Hash setO(L)O(L) avgO(NL)O(N \cdot L)
Sorted array + binary searchO(LlogN)O(L \log N)O(LlogN)O(L \log N)O(NL)O(N \cdot L)
TrieO(L)O(L)O(L)O(L)✓ (DFS)O(NLΣ)O(N \cdot L \cdot \Sigma) worst case

Where LL is word length, NN is word count, and Σ\Sigma is alphabet size. The trie wins when prefix operations dominate. If you only need membership checks and don’t care about prefixes, a hash set is simpler and faster in practice. The trie’s memory overhead is the main downside — each node carries pointer overhead regardless of how many children it actually has.

Complexity

OperationTimeSpace
InsertO(L)O(L)O(L)O(L) new nodes worst case
SearchO(L)O(L)O(1)O(1)
StartsWithO(L)O(L)O(1)O(1)
DeleteO(L)O(L)O(1)O(1) (freeing nodes)
Build from NN wordsO(NL)O(N \cdot L)O(NLΣ)O(N \cdot L \cdot \Sigma) worst case

LL is the length of the word. Space is bounded by the total number of unique prefixes across all inserted words times the children structure size.

Key takeaways

  • Every path from root is a prefix — the trie’s structure inherently encodes all prefixes, making prefix queries O(L)O(L) with zero extra work.
  • Shared prefixes share nodes — words with common beginnings reuse the same path, which is the core reason tries beat hash sets for prefix-heavy workloads.
  • Use an array of size 26 for interviews — when the alphabet is lowercase English, a fixed-size array gives constant-time child access and is simpler to code under pressure.
  • Tries enable early termination on grids — in word search problems, walking the trie alongside the DFS lets you prune entire branches the moment no dictionary word matches the current path.
  • Space is the tradeoff — tries can use significantly more memory than hash sets due to per-node pointer overhead; only reach for them when prefix operations are essential.

Practice problems

ProblemDifficultyKey idea
Implement Trie (Prefix Tree)🟡 MediumBuild insert, search, and startsWith from scratch using a TrieNode with children array
Design Add and Search Words Data Structure🟡 MediumTrie with DFS branching on wildcard . characters
Word Search II🔴 HardBuild a trie from the dictionary and DFS on the board simultaneously for early pruning
Replace Words🟡 MediumInsert roots into a trie, then find the shortest matching prefix for each word
Search Suggestions System🟡 MediumWalk the trie character by character and DFS-collect up to 3 lexicographically smallest words

Relation to other topics

  • Suffix tree is a compressed trie of all suffixes of a string. It enables O(M)O(M) substring search where MM is the pattern length, but construction is complex (Ukkonen’s algorithm).
  • Radix tree (compressed trie / Patricia tree) merges single-child chains into one edge with a multi-character label. Same asymptotic complexity, but far less memory in practice. Used in Linux kernel routing tables and HTTP routers.
  • Aho-Corasick builds a trie of patterns then adds failure links (like KMP) to enable multi-pattern matching in O(N+M+Z)O(N + M + Z) where ZZ is the number of matches. It’s what powers grep -F with multiple patterns.
  • DAWG (Directed Acyclic Word Graph) shares both prefixes and suffixes, giving minimal space for a fixed dictionary.

Build on these first

These topics supply the mental model or underlying structure that this page assumes.

What this enables

Once the current idea feels natural, these are the most useful next jumps.

Related directions

These topics live nearby conceptually, even if they are not direct prerequisites.

More from Strings

Stay in the same family when you want parallel variations of the same mental model.

Paths that include this topic

Follow one of these sequences if you want a guided next step instead of open-ended browsing.

Ordered structures

See how order can come from sorted arrays, search trees, skip lists, disk-friendly indexes, heaps, and prefix trees.

String matching

Move from prefix reuse and rolling hashes to suffix-based indexing and automata.

From the blog

Pair the atlas with recent writing from the rest of the site when you want a broader engineering perspective alongside the topic graph.