Trie insertion and search in Data Structures Theory - Time & Space Complexity
When working with tries, it is important to understand how the time to insert or search words grows as the words get longer.
We want to know how the number of steps changes when we add longer words or more words.
Analyze the time complexity of the following code snippet.
class TrieNode:
def __init__(self):
self.children = {}
self.is_end = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.is_end = True
def search(self, word):
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.is_end
This code inserts words into a trie and searches for words by following nodes for each character.
- Primary operation: Looping through each character of the input word.
- How many times: Once for each character in the word (length n).
Each step processes one character, so the total steps grow directly with the word length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The time grows linearly as the word length increases.
Time Complexity: O(n)
This means the time to insert or search grows directly with the length of the word.
[X] Wrong: "Trie operations depend on the number of words stored, so more words always mean slower insert or search."
[OK] Correct: Actually, insert and search time depends mainly on the length of the word, not how many words are stored.
Understanding trie time complexity helps you explain why tries are efficient for prefix searches and autocomplete features.
"What if we changed the trie to store only lowercase letters and used a fixed-size array instead of a dictionary for children? How would the time complexity change?"
Practice
Solution
Step 1: Understand Trie structure
A Trie stores words by breaking them into letters and linking them in a tree structure.Step 2: Identify purpose
This structure allows fast searching of words by prefixes, unlike storing whole words as strings or hashes.Final Answer:
To store words letter by letter in a tree for fast prefix search -> Option AQuick Check:
Trie = letter-by-letter tree [OK]
- Thinking Trie stores whole words as strings
- Confusing Trie with hash tables
- Assuming Trie stores words randomly
Solution
Step 1: Review insertion steps
Insertion checks each letter; if a letter node is missing, it creates it.Step 2: Mark end of word
After all letters are inserted, the last node is marked to show the word ends there.Final Answer:
Add nodes for each letter if missing and mark the last node as end of word -> Option DQuick Check:
Insert = add letters + mark end [OK]
- Inserting whole word as one node
- Not marking the end of word
- Replacing existing nodes unnecessarily
cat, car, and dog, what will be the result of searching for cap?Solution
Step 1: Check prefix nodes
The Trie has nodes for 'c' and 'a' from 'cat' and 'car'.Step 2: Verify next letter node
There is no 'p' node after 'a', so 'cap' is not found.Final Answer:
False, because 'p' node does not exist after 'ca' -> Option CQuick Check:
Missing letter node means word not found [OK]
- Assuming prefix presence means full word found
- Confusing similar words as found
- Expecting errors instead of false
for letter in word:
if letter in current_node:
current_node = current_node[letter]
else:
current_node[letter] = {}
current_node['end'] = TrueSolution
Step 1: Analyze insertion logic
When a new letter node is created, the code does not move current_node to this new node.Step 2: Identify fix
After adding a new node, current_node must be updated to that node to continue insertion correctly.Final Answer:
The else block should update current_node after adding new node -> Option BQuick Check:
Update current_node after adding new letter node [OK]
- Not updating current_node after insertion
- Setting 'end' marker inside loop incorrectly
- Confusing iteration over letters vs indices
bat, bath, and baton into a Trie. How many nodes will the Trie have after all insertions?Solution
Step 1: Insert 'bat'
Creates nodes: 'b', 'a', 't' -> 3 nodes (root is not counted as a node).Step 2: Insert 'bath'
'b', 'a', 't' exist; add 'h' -> 1 new node; total 4 nodes.Step 3: Insert 'baton'
'b', 'a', 't' exist; add 'o', 'n' -> 2 new nodes; total 6 nodes.Step 4: Count 'end' markers as nodes
Each word end is marked, adding 3 'end' markers as nodes; total nodes = 6 + 3 = 9 nodes.Step 5: Confirm total nodes
Nodes: b, a, t, h, o, n plus 3 'end' markers = 9 nodes.Final Answer:
9 nodes -> Option AQuick Check:
Letter nodes + end markers = 9 [OK]
- Counting duplicate nodes multiple times
- Ignoring shared prefixes
- Miscounting letters in longer words
- Not counting 'end' markers as nodes
Ready to prove it?
Pass the test and this pattern moves unknown
