Bird
Raised Fist0
DSA Pythonprogramming

Trie Insert Operation in DSA Python

Choose your learning style10 modes available
Mental Model
A trie stores words by sharing common letters in a tree, adding new letters as needed.
Analogy: Imagine a tree of roads where each letter is a street sign; inserting a word means building new streets only when they don't exist yet.
root
 ↓
{}  (empty trie with root node)
Dry Run Walkthrough
Input: Insert words: 'cat', then 'car'
Goal: Build a trie that stores both words sharing the common prefix 'ca'
Step 1: Insert 'c' from 'cat' at root
root
 ↓
{'c': {}}
Why: Start the path for the word with first letter 'c'
Step 2: Insert 'a' after 'c'
root
 ↓
{'c': {'a': {}}}
Why: Add next letter 'a' continuing the word path
Step 3: Insert 't' after 'a' and mark end of word
root
 ↓
{'c': {'a': {'t': {'$': true}}}}
Why: Complete the word 'cat' by adding 't' and marking word end
Step 4: Insert 'c' from 'car' at root (exists)
root
 ↓
{'c': {'a': {'t': {'$': true}}}}
Why: Reuse existing 'c' node for new word
Step 5: Insert 'a' after 'c' (exists)
root
 ↓
{'c': {'a': {'t': {'$': true}}}}
Why: Reuse existing 'a' node for new word
Step 6: Insert 'r' after 'a' and mark end of word
root
 ↓
{'c': {'a': {'t': {'$': true}, 'r': {'$': true}}}}
Why: Add new branch 'r' to complete 'car' and mark word end
Result:
root
 ↓
{'c': {'a': {'t': {'$': true}, 'r': {'$': true}}}}
Annotated Code
DSA Python
class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

class Trie:
    def __init__(self):
        self.root = TrieNode()

    def insert(self, word: str) -> None:
        node = self.root
        for char in word:
            if char not in node.children:
                node.children[char] = TrieNode()  # create new node if missing
            node = node.children[char]  # move to child node
        node.is_end = True  # mark end of word

    def __str__(self):
        # Helper to print trie structure for verification
        def dfs(node):
            result = {}
            for ch, child in node.children.items():
                result[ch] = dfs(child)
            if node.is_end:
                result['$'] = True
            return result
        return str(dfs(self.root))

# Driver code
trie = Trie()
trie.insert('cat')
trie.insert('car')
print(trie)
if char not in node.children: node.children[char] = TrieNode()
create new node if letter path does not exist
node = node.children[char]
advance to child node to continue insertion
node.is_end = True
mark current node as end of a complete word
OutputSuccess
{'c': {'a': {'t': {'$': True}, 'r': {'$': True}}}}
Complexity Analysis
Time: O(m) because we process each of the m letters in the word once
Space: O(m) in worst case when all letters are new and need new nodes
vs Alternative: Compared to storing words in a list, trie insert is faster for prefix queries but uses more space for nodes
Edge Cases
Insert empty string
Marks root as end of word without adding nodes
DSA Python
node.is_end = True
Insert word that is prefix of existing word (e.g., 'ca')
Marks existing node as end of word without adding nodes
DSA Python
node.is_end = True
Insert duplicate word
No new nodes added, just marks end again
DSA Python
node.is_end = True
When to Use This Pattern
When you need to store many words sharing prefixes for fast prefix search or autocomplete, use a trie insert pattern to build the structure efficiently.
Common Mistakes
Mistake: Not marking the end of word node, so words are not recognized as complete
Fix: Always set node.is_end = True after inserting all letters
Mistake: Creating new nodes even if the letter path already exists
Fix: Check if letter exists before creating new node to reuse existing paths
Summary
Inserts words letter by letter into a tree structure sharing common prefixes.
Use when you want to store many words efficiently and support prefix-based queries.
The key is to reuse existing letter paths and mark the end of each complete word.

Practice

(1/5)
1. What is the main purpose of the insert operation in a Trie data structure?
easy
A. To delete a word from the Trie
B. To add a new word character by character into the Trie
C. To search for a word in the Trie
D. To count the total words stored in the Trie

Solution

  1. Step 1: Understand the insert operation

    The insert operation adds each character of a word into the Trie one by one, creating nodes if they don't exist.
  2. Step 2: Compare with other operations

    Deleting removes words, searching checks presence, counting totals words. Insert specifically adds words.
  3. Final Answer:

    To add a new word character by character into the Trie -> Option B
  4. Quick Check:

    Insert = Add word stepwise [OK]
Hint: Insert means adding word letters step-by-step [OK]
Common Mistakes:
  • Confusing insert with search or delete
  • Thinking insert counts words
  • Assuming insert removes words
2. Which of the following is the correct way to start inserting a word "cat" into an empty Trie in Python?
easy
A. for char in "cat": current = current.children[char] if char in current.children else current.children[char] = TrieNode()
B. for char in "cat": current = current.children[char]
C. for char in "cat": current.children[char] = TrieNode(); current = current.children[char]
D. for char in "cat": if char not in current.children: current.children[char] = TrieNode(); current = current.children[char]

Solution

  1. Step 1: Check condition before adding node

    We must check if the character node exists before creating a new one to avoid overwriting.
  2. Step 2: Move current pointer correctly

    After ensuring the node exists, move current to that child node for next character insertion.
  3. Final Answer:

    for char in "cat": if char not in current.children: current.children[char] = TrieNode(); current = current.children[char] -> Option D
  4. Quick Check:

    Check existence then add and move [OK]
Hint: Check if node exists before adding new one [OK]
Common Mistakes:
  • Not checking if child node exists before assignment
  • Not moving current pointer after insertion
  • Overwriting existing nodes
3. Consider the following code snippet for inserting the word "dog" into a Trie. What will be the printed output after insertion?
class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

root = TrieNode()

word = "dog"
current = root
for char in word:
    if char not in current.children:
        current.children[char] = TrieNode()
    current = current.children[char]
current.is_end = True

print(list(root.children.keys()))
medium
A. ['d']
B. ['o']
C. ['g']
D. []

Solution

  1. Step 1: Insert characters one by one

    The first character 'd' is added as a child of root, so root.children has key 'd'.
  2. Step 2: Check what is printed

    Printing root.children.keys() shows the first level keys, which is ['d'] after insertion.
  3. Final Answer:

    ['d'] -> Option A
  4. Quick Check:

    Root children keys after insert = ['d'] [OK]
Hint: Root children keys show first inserted letters [OK]
Common Mistakes:
  • Expecting all letters at root level
  • Printing keys of last node instead of root
  • Confusing keys with values
4. The following code attempts to insert the word "bat" into a Trie but has a bug. What is the error?
class TrieNode:
    def __init__(self):
        self.children = {}
        self.is_end = False

root = TrieNode()
word = "bat"
current = root
for char in word:
    current.children[char] = TrieNode()
current = current.children[char]
current.is_end = True
medium
A. The children dictionary is not initialized
B. The is_end flag is set before inserting all characters
C. The current pointer is moved outside the loop, causing nodes to not be chained properly
D. The loop variable 'char' is not defined

Solution

  1. Step 1: Analyze loop and pointer movement

    The line moving current pointer is outside the loop, so current only moves after loop ends, not per character.
  2. Step 2: Understand effect on insertion

    Nodes for each character are created directly under root (no chaining), and only the last node's is_end is set.
  3. Final Answer:

    The current pointer is moved outside the loop, causing nodes to not be chained properly -> Option C
  4. Quick Check:

    Pointer must move inside loop to build chain [OK]
Hint: Move current pointer inside loop to link nodes [OK]
Common Mistakes:
  • Moving pointer outside loop
  • Not creating nodes conditionally
  • Setting is_end too early
5. You want to insert multiple words ["apple", "app", "ape"] into a Trie. After insertion, which of the following statements is TRUE about the Trie structure?
hard
A. The node for 'l' after "app" exists only for "apple"
B. The node for 'p' after 'ap' will have is_end = True for both "app" and "ape"
C. Each word creates a completely separate branch from root
D. The root node's is_end flag will be True after insertion

Solution

  1. Step 1: Understand shared prefixes in Trie

    Words "apple", "app", and "ape" share prefix "ap"; nodes for 'a' and 'p' are shared.
  2. Step 2: Check is_end flags for words

    "app" ends at second 'p' node, so that node's is_end = True; "apple" continues to 'l' and 'e', so 'l' node is not end, but 'e' node is end.
  3. Step 3: Analyze options

    The node for 'p' after 'ap' will have is_end = True for both "app" and "ape" is wrong because 'p' node cannot be end for both "app" and "ape"; 'ape' ends at 'e' node. Each word creates a completely separate branch from root is wrong because branches share prefix nodes. The root node's is_end flag will be True after insertion is wrong because root node is not end of any word.
  4. Final Answer:

    The node for 'l' after "app" exists only for "apple" -> Option A
  5. Quick Check:

    Shared prefix nodes, is_end marks word ends [OK]
Hint: Shared prefixes share nodes; is_end marks word ends only [OK]
Common Mistakes:
  • Assuming each word has separate root branch
  • Marking is_end on wrong nodes
  • Setting root is_end True incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard