What does the 'isEndOfWord' flag represent?
Updated Apr 28, 2026
Short answer
The isEndOfWord flag indicates whether the path from the root to the current Trie node forms a complete stored word. It distinguishes complete words from prefixes that are only part of longer words. Without this flag, a Trie could not tell the difference between a word like "car" and a prefix of another word like "cart".
Deep explanation
A Trie stores words character by character, where each node represents a character and the path from the root to a node represents a string.
However, reaching a node does not always mean a complete word exists at that point. A node may only represent a prefix shared by longer words.
For example, consider inserting these words:
carcartThe Trie looks like:
root | c | a | r* | t*The * represents isEndOfWord = true.
- The node containing
rhasisEndOfWord = truebecause"car"is a complete word. - The node containing
talso hasisEndOfWord = truebecause"cart"is a complete word. - The nodes containing
candahaveisEndOfWord = falsebecause"c"and"ca"are only prefixes.
A Trie node often looks like this:
class TrieNode: def __init__(self): self.children = {} self.isEndOfWord = FalseWhen inserting a word, the flag is set only on the final character node:
def insert(word): node = root
for char in word: if char not in node.children: node.children[char] = TrieNode()
node = node.children[char]
node.isEndOfWord = TrueWhy the flag is necessary
Consider inserting only:
appleThe Trie contains nodes for:
a -> p -> p -> l -> eIf a user searches for "app", the Trie can successfully follow the path:
a -> p -> pBut "app" was never inserted. The isEndOfWord flag on the second p node tells us that the path exists only as a prefix, not as a complete word.
The search operation uses the flag:
def search(word): node = root
for char in word: if char not in node.children: return False
node = node.children[char]
return node.isEndOfWordThe final check is important:
- Path exists +
isEndOfWord = true→ word exists. - Path exists +
isEndOfWord = false→ only a prefix exists. - Path does not exist → word is not stored.
Relationship with shared prefixes
The flag allows multiple words to share nodes while still keeping track of individual words.
For example:
Words:appappleapplicationThe Trie shares the common prefix:
a -> p -> pBut the nodes have different meanings:
a -> p -> p* -> l -> e* | l -> i -> c -> a -> t -> i -> o -> n*The first * marks "app" as a complete word, while the other flags mark "apple" and "application".
Trade-offs
Adding an isEndOfWord boolean requires a small amount of extra memory per Trie node, but it provides essential information.
Without the flag:
- Prefix checks still work.
- Traversal still works.
- Exact word searches become incorrect.
With the flag:
- Exact searches are accurate.
- Prefix and autocomplete operations can still be performed.
- Multiple words with shared prefixes can be stored efficiently.
Real-world example
A dictionary application may store words for spell checking:
catcatalogThe Trie stores:
root | c | a | t* | a | l | o | g*When checking the word "cat":
def is_word(word): node = root
for char in word: if char not in node.children: return False node = node.children[char]
return node.isEndOfWordThe application reaches the t node and sees:
node.isEndOfWord == Trueso "cat" is a valid word.
If it checks "ca", the path exists, but the a node has:
node.isEndOfWord == Falseso "ca" is only a prefix, not a valid dictionary entry.
Common mistakes
- * Assuming every Trie node represents a complete word instead of checking `isEndOfWord`.
- * Forgetting to set `isEndOfWord` when inserting a new word.
- * Using `isEndOfWord` to mean the node has no children, which is incorrect.
- * Not marking shorter words that are prefixes of longer words, such as `"app"` when `"apple"` also exists.
- * Removing the flag during optimization and breaking exact word searches.
- * Confusing a prefix match with a complete word match.
Follow-up questions
- Why can't we determine the end of a word by checking if a node has no children?
- What value should isEndOfWord have for nodes that only represent prefixes?
- How does isEndOfWord help when deleting a word from a Trie?
- Can a Trie work without an isEndOfWord flag?
- How is isEndOfWord different from storing the entire word at the final node?