Trie Insert Operation in DSA Go - Time & Space Complexity
We want to understand how the time to insert a word into a trie changes as the word gets longer.
How does the number of steps grow when we add longer words?
Analyze the time complexity of the following code snippet.
func (t *TrieNode) Insert(word string) {
node := t
for _, ch := range word {
if node.children[ch] == nil {
node.children[ch] = &TrieNode{children: make(map[rune]*TrieNode)}
}
node = node.children[ch]
}
node.isEnd = true
}
This code inserts each character of a word into the trie, creating new nodes if needed.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each character of the input word.
- How many times: Exactly once for each character in the word (length n).
Each character in the word requires one step to check or create a node.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps |
| 100 | About 100 steps |
| 1000 | About 1000 steps |
Pattern observation: The steps grow directly with the word length, so doubling the word doubles the work.
Time Complexity: O(n)
This means the time to insert grows linearly with the length of the word.
[X] Wrong: "Inserting a word takes constant time because we just add nodes once."
[OK] Correct: Each character must be processed, so longer words take more time, not the same time.
Understanding this helps you explain how tries efficiently handle many words, especially when words share prefixes.
"What if we changed the data structure for children from a map to a fixed-size array? How would the time complexity change?"
Practice
Insert operation in a Trie data structure?Solution
Step 1: Understand the Insert operation
The Insert operation adds a word by creating nodes for each character if they don't exist.Step 2: Differentiate from other operations
Deleting removes words, searching finds words, counting totals words. Insert specifically adds words.Final Answer:
To add a new word by creating nodes for each character -> Option BQuick Check:
Insert = Add word nodes [OK]
- Confusing insert with search or delete
- Thinking insert counts words
- Assuming insert modifies existing words
Solution
Step 1: Identify correct children type for TrieNode
Children should map characters (rune) to TrieNode pointers for branching.Step 2: Check isEnd type
isEnd is a boolean indicating if node ends a word.Final Answer:
type TrieNode struct { children map[rune]*TrieNode; isEnd bool } -> Option AQuick Check:
Children map[rune]*TrieNode and isEnd bool [OK]
- Using slice instead of map for children
- Wrong data types for children or isEnd
- Using string keys instead of rune
Solution
Step 1: Insert "cat" and "car" into Trie
Both words share prefix 'c' -> 'a'. After insertion, node 'a' has children 't' and 'r'.Step 2: Check if node 'a' under 'c' has children
Since 'a' node has two children nodes ('t' and 'r'), it has children, so true.Final Answer:
true -> Option CQuick Check:
Shared prefix node has children = true [OK]
- Assuming node 'a' has no children
- Confusing node existence with children presence
- Expecting nil or error instead of true
func (t *TrieNode) Insert(word string) {
node := t
for _, ch := range word {
if node.children[ch] == nil {
node.children[ch] = &TrieNode{}
}
node = node.children[ch]
}
node.isEnd = true
}Solution
Step 1: Check initialization of children map
The children map must be initialized (e.g., make(map[rune]*TrieNode)) before inserting nodes.Step 2: Identify impact of missing initialization
Without initialization, accessing children[ch] causes runtime panic (nil map assignment).Final Answer:
children map is not initialized before use -> Option AQuick Check:
Uninitialized map causes runtime error [OK]
- Ignoring map initialization
- Misunderstanding rune vs int for keys
- Thinking isEnd needs early assignment
Solution
Step 1: Analyze first characters of all words
All words start with the letter 'g', so root node will have one child for 'g'.Step 2: Understand Trie root children count
Root children count equals distinct first letters of inserted words, here only 'g'.Final Answer:
1, because all words start with 'g' -> Option DQuick Check:
Root children = distinct first letters = 1 [OK]
- Counting words instead of unique first letters
- Assuming root has no children
- Confusing shared prefixes with root children count
Ready to prove it?
Pass the test and this pattern moves unknown
