Implement Trie (Prefix Tree)

Algorithms
Medium
Google
104.9K views

Implement the Trie data structure, which supports `insert`, `search`, and `startsWith` operations.

Why Interviewers Ask This

Google asks this to evaluate a candidate's mastery of pointer manipulation and memory management. It tests the ability to design nested data structures that optimize prefix lookups, a core requirement for autocomplete systems. Interviewers specifically assess how you handle edge cases like null pointers, empty strings, and partial word matches while maintaining O(m) time complexity.

How to Answer This Question

1. Clarify requirements immediately: Ask if words are case-sensitive, if we need to count occurrences, or handle special characters, as Google values precision. 2. Define the node structure: Propose a class with a map or array of children nodes and a boolean flag to mark end-of-word, explaining why an array is faster for ASCII but a map saves space for Unicode. 3. Walk through 'insert': Describe traversing character by character, creating new nodes only when paths diverge, and marking the final node. 4. Explain 'search' and 'startsWith': Differentiate them by checking if the path exists versus if the path ends at a valid word marker. 5. Analyze complexity: Explicitly state O(L) time where L is word length and O(N*L) space, demonstrating awareness of scalability.

Key Points to Cover

  • Demonstrating clear separation between path existence (startsWith) and word validity (search)
  • Choosing between array vs. hash map based on character set constraints
  • Explicitly handling edge cases like null inputs or empty strings
  • Correctly managing the boolean flag to distinguish prefixes from complete words
  • Articulating O(L) time complexity for all operations

Sample Answer

To implement a Trie efficiently, I would start by defining a Node class containing a map for children and a boolean flag indicating if a word ends there. This structure allows us to dynamically allocate memory only for existing prefixes. For the insert operation, I traverse the tree from the root. If a character doesn't exist in the current node's children, I create a new node. Once the entire string is processed, I set the end-of-word flag to true. This ensures we don't overwrite existing words but correctly add new ones. When searching, I follow the same path. The critical distinction is that search requires the final node to have its end-of-word flag set to true, whereas startsWith only verifies that the entire path exists without needing the flag. I would also consider using a fixed-size array of 26 for lowercase English letters instead of a hash map to reduce overhead, as Google often prioritizes raw performance in low-level implementations. Finally, I would ensure my code handles empty strings gracefully by returning false for search and true for startsWith, as these are common edge cases in production environments.

Common Mistakes to Avoid

  • Confusing the logic for 'search' and 'startsWith' by forgetting to check the end-of-word flag
  • Using a global variable or static counter which breaks thread safety in concurrent systems
  • Failing to initialize the root node properly, leading to null pointer exceptions during traversal
  • Ignoring memory optimization by creating nodes for every single character even when not needed

Practice This Question with AI

Answer this question orally or via text and get instant AI-powered feedback on your response quality, structure, and delivery.

Start Practicing

Related Interview Questions

Browse all 145 Algorithms questionsBrowse all 87 Google questions