Tries (Prefix Trees) — Complete Guide

Sanjeev SharmaSanjeev Sharma
5 min read

Advertisement

What is a Trie?

A Trie (prefix tree) is a tree where each node represents one character. Paths from root to a node spell out a string prefix. It enables O(L) insert, search, and prefix-check (L = string length).


Core Trie Node Structure

class TrieNode:
    def __init__(self):
        self.children = {}   # or [None]*26 for lowercase only
        self.is_end = False

The 5 Core Trie Patterns

Pattern 1 — Basic Trie (Insert / Search / StartsWith)

def insert(word):
    node = root
    for c in word:
        if c not in node.children:
            node.children[c] = TrieNode()
        node = node.children[c]
    node.is_end = True

def search(word):
    node = root
    for c in word:
        if c not in node.children: return False
        node = node.children[c]
    return node.is_end

def starts_with(prefix):
    node = root
    for c in prefix:
        if c not in node.children: return False
        node = node.children[c]
    return True

Pattern 2 — Trie + DFS for Word Search II

Build a trie from the word list. DFS on the grid, traversing the trie simultaneously — prune when no trie path exists.

Pattern 3 — Trie with Count / Delete

Track count of words with this prefix. Decrement on delete.

Pattern 4 — XOR Trie (Max XOR)

Build a binary trie (bit by bit, MSB first). For each number, greedily take opposite bit to maximize XOR.

# Binary trie insert (bit by bit)
def insert(num):
    node = root
    for bit in range(31, -1, -1):
        b = (num >> bit) & 1
        if b not in node.children:
            node.children[b] = TrieNode()
        node = node.children[b]

Pattern 5 — Autocomplete / Ranked Suggestions

Trie with sorted word lists at each node, or DFS from prefix node to collect all words.


Complexity Reference

OperationTimeSpace
Insert wordO(L)O(L) per word
Search wordO(L)O(1)
Prefix searchO(L)O(1)
Word Search IIO(MN4^L) prunedO(total word chars)
Max XOR pairO(32*n)O(32*n)

5-Language Trie Node

C — Array-based

typedef struct TrieNode {
    struct TrieNode* ch[26];
    int isEnd;
} TrieNode;
TrieNode* newNode(){
    TrieNode* n=calloc(1,sizeof(TrieNode)); n->isEnd=0; return n;
}
void insert(TrieNode* root, char* word){
    TrieNode* cur=root;
    for(;*word;word++){
        int i=*word-'a';
        if(!cur->ch[i]) cur->ch[i]=newNode();
        cur=cur->ch[i];
    }
    cur->isEnd=1;
}

C++ — unordered_map

struct TrieNode {
    unordered_map<char,TrieNode*> ch;
    bool isEnd=false;
};
class Trie {
    TrieNode* root=new TrieNode();
public:
    void insert(string w){
        auto* cur=root;
        for(char c:w){if(!cur->ch.count(c))cur->ch[c]=new TrieNode();cur=cur->ch[c];}
        cur->isEnd=true;
    }
    bool search(string w){
        auto* cur=root;
        for(char c:w){if(!cur->ch.count(c))return false;cur=cur->ch[c];}
        return cur->isEnd;
    }
};

Java — array children

class Trie {
    Trie[] ch = new Trie[26];
    boolean isEnd;
    public void insert(String w){
        Trie cur=this;
        for(char c:w.toCharArray()){
            int i=c-'a';
            if(cur.ch[i]==null) cur.ch[i]=new Trie();
            cur=cur.ch[i];
        }
        cur.isEnd=true;
    }
    public boolean search(String w){
        Trie cur=this;
        for(char c:w.toCharArray()){int i=c-'a';if(cur.ch[i]==null)return false;cur=cur.ch[i];}
        return cur.isEnd;
    }
}

JavaScript — object children

class TrieNode {
    constructor(){ this.ch={}; this.isEnd=false; }
}
class Trie {
    constructor(){ this.root=new TrieNode(); }
    insert(w){ let n=this.root; for(const c of w){if(!n.ch[c])n.ch[c]=new TrieNode();n=n.ch[c];}n.isEnd=true; }
    search(w){ let n=this.root; for(const c of w){if(!n.ch[c])return false;n=n.ch[c];}return n.isEnd; }
}

Problem Index

#ProblemPatternDifficulty
01Implement TrieBasic TrieMedium
02Design Add and Search WordsTrie + wildcard DFSMedium
03Word Search IITrie + Grid DFSHard
04Replace WordsTrie prefix replacementMedium
05Map Sum PairsTrie with value sumMedium
06Maximum XOR of Two NumbersBinary TrieMedium
07Longest Word in DictionaryTrie + BFSMedium
08Index Pairs of a StringTrie text matchingEasy
09Search Suggestions SystemTrie + sorted listsMedium
10Stream of CharactersTrie reverse suffixHard
11Palindrome PairsTrie + palindrome checkHard
12Concatenated WordsTrie + word breakHard
13Count Distinct SubstringsSuffix TrieMedium
14Prefix and Suffix SearchDouble-end trieHard
15Short Encoding of WordsTrie + suffixMedium
16Maximum XOR With an ElementBinary Trie + offlineHard
17Count Words Beginning PrefixTrie countEasy
18Sum of Prefix ScoresTrie prefix countHard
19Find the Length of the Longest Common PrefixTrie digitMedium
20Tries Master RecapCheatsheet

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro