The O(n) Club: Trie (Prefix Tree): Where Your Prefix Issues Go To Die
⚡ TL;DR
Tries, aka prefix trees, are the go-to when you want to answer annoying questions like “Does any word start with ‘auto’?” faster than your coffee gets cold. They keep your strings as tidy as a Marie Kondo Netflix special. If you’re bored, here’s the absolute basics in Java:
// Java TrieNode: minimal and unimpressed class TrieNode { TrieNode[] children = new TrieNode[26]; boolean isWord; }
🧠 How Devs Usually Mess This Up
Some devs think tries are just binary search trees after a wild night out (spoiler: they’re not). Others imagine loading every word means magic space-saving. Reality check: if your data is more “unique snowflake” than “copy-paste,” tries will gobble memory like a Chrome tab hoarding RAM. And don’t forget the classic fail—assuming every node finishing a prefix is a real word. If you miss marking your word ends, get ready to play “Is ‘app’ a word or just the opening act for ‘apple’?” forever.
🔍 What’s Actually Going On
Picture a call center, but each agent only answers to one letter. You follow the path for “a-p-p-l-e”—if there’s no agent on the next line, your query dies. If you make it to a node with a “yes, this is a word” stamp, you win. Common prefixes share space (all “app” words use the same path at the start), so autocomplete and spell-check work like a dream—as long as your words actually use the same beginnings.
🛠️ PseudoCode
- Insert a Word:
- Start at the root node.
- For each character in your word:
- If the child exists, walk there like you own the place.
- If not, make a new node and stroll in.
- Mark the last node as isWord = true (
end-of-word
badge earned).
// Java-style void insert(String word) { TrieNode node = root; for (char c : word.toCharArray()) { if (node.children[c - 'a'] == null) node.children[c - 'a'] = new TrieNode(); node = node.children[c - 'a']; } node.isWord = true; }
- Search a Word:
- Start at the root, check characters one by one.
- If any path is missing, answer is “nope”.
- If you make it, return isWord—that’s your finish line.
- Check a Prefix:
- Walk as above, but only care if you can traverse the entire prefix. Don’t care about isWord here.
💻 The Code
// Java Trie in action
class Trie {
private static class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isWord;
}
private final TrieNode root = new TrieNode();
public void insert(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
int idx = c - 'a';
if (node.children[idx] == null)
node.children[idx] = new TrieNode();
node = node.children[idx];
}
node.isWord = true;
}
public boolean search(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
int idx = c - 'a';
if (node.children[idx] == null)
return false;
node = node.children[idx];
}
return node.isWord;
}
public boolean startsWith(String prefix) {
TrieNode node = root;
for (char c : prefix.toCharArray()) {
int idx = c - 'a';
if (node.children[idx] == null)
return false;
node = node.children[idx];
}
return true;
}
}
⚠️ Pitfalls, Traps & Runtime Smacks
- Case (in)sensitivity? This code is for lowercase ‘a’-‘z’ only. Give it an uppercase character, and watch it implode.
- Mega alphabets? If your trie only holds “cat” and “dog,” you’re wasting space for 24 letters at every node. Sorry, English isn’t always efficient.
- Null pointer drama: Forget to check for null? Get ready for runtime rants.
- Not a hashmap, not O(1): All main ops are O(length of word/prefix). Your speedy hash table is still faster for random lookup.
🧠 Interviewer Brain-Tattoo
“A trie will never judge your spelling—but if you don’t mark the end of your words, it’ll never forgive you either.”