Hone logo
Hone
Problems

React Trie for Autocomplete

This challenge focuses on implementing a Trie data structure within a React application to power an efficient autocomplete feature. You will build a reusable Trie component that can store and query string data, enabling fast suggestions as a user types in an input field. This is a fundamental problem for building responsive search and suggestion functionalities.

Problem Description

Your task is to create a React component that utilizes a Trie data structure. The Trie should be populated with a predefined list of strings (e.g., country names, product names). The component should then expose an API or mechanism to query this Trie based on a user's input string and return all matching strings that start with the given prefix.

Key Requirements:

  1. Trie Implementation: Implement a functional Trie data structure in TypeScript. This Trie should support at least two core operations:
    • insert(word: string): Adds a word to the Trie.
    • search(prefix: string): Returns an array of all words stored in the Trie that start with the given prefix.
  2. React Component Integration: Create a React component that encapsulates the Trie logic. This component should:
    • Initialize the Trie with a provided list of strings during its setup (e.g., in useEffect).
    • Accept a prefix prop (or manage its own internal state for the input) that represents the current user input.
    • Provide a way to retrieve the autocomplete suggestions based on the current prefix. This could be through a render prop, a callback function, or by managing the suggestions state within the component and exposing it.
  3. Type Safety: Ensure all implementations are written in TypeScript, leveraging its type system for robustness.

Expected Behavior:

When a user types into an associated input field, the component should query the Trie with the input string. The search function of the Trie should be invoked, and the returned list of matching strings should be displayed as suggestions.

Edge Cases to Consider:

  • Empty prefix input: Should return all words or an empty list, depending on desired behavior (returning all is generally preferred for initial state).
  • Prefix not found: Should return an empty list of suggestions.
  • Case sensitivity: Decide whether the Trie should be case-sensitive or case-insensitive. For this challenge, assume case-insensitivity by converting all inserted words and search prefixes to lowercase.
  • Duplicate words: The Trie should handle duplicate insertions gracefully (e.g., by not storing them multiple times).

Examples

Example 1: Basic Insertion and Search

// Assume a Trie class is implemented
const trie = new Trie();
trie.insert("apple");
trie.insert("apricot");
trie.insert("banana");

// Searching for "ap"
const suggestions = trie.search("ap");
// Expected Output: ["apple", "apricot"]

Explanation: The words "apple" and "apricot" both start with the prefix "ap", so they are returned. "banana" does not start with "ap".

Example 2: Case-Insensitivity

// Assume a Trie class is implemented and handles case-insensitivity
const trie = new Trie();
trie.insert("Apple");
trie.insert("Apricot");

// Searching for "ap" (lowercase)
const suggestions = trie.search("ap");
// Expected Output: ["apple", "apricot"] (or the original casing if preserved)

Explanation: Due to case-insensitivity, searching for "ap" retrieves words inserted with different casing. For this challenge, let's aim to return the original casing of the words.

Example 3: No Matches

// Assume a Trie class is implemented
const trie = new Trie();
trie.insert("cat");
trie.insert("car");

// Searching for "dog"
const suggestions = trie.search("dog");
// Expected Output: []

Explanation: No words in the Trie start with the prefix "dog".

Constraints

  • The Trie should be able to store at least 10,000 unique strings.
  • The length of each string (word) will not exceed 50 characters.
  • The number of concurrent searches performed should not significantly impact UI responsiveness. A reasonable performance target is to return suggestions within 50ms for typical inputs.
  • The solution must be implemented in TypeScript.
  • The React component should be functional.

Notes

  • Consider how to represent the Trie nodes. A common approach is to use an object or Map for children, where keys are characters and values are child Trie nodes.
  • A flag on a node can indicate if a complete word ends at that node.
  • For the search operation, you'll need to traverse the Trie to the node representing the end of the prefix, and then perform a Depth-First Search (DFS) or Breadth-First Search (BFS) from that node to find all words.
  • Think about how your React component will manage the Trie's state and how it will communicate the suggestions back to its parent or display them. Using hooks like useState and useEffect will be crucial.
  • For the purpose of this challenge, you can hardcode the initial list of strings to populate the Trie within the component, or accept it as a prop.
Loading editor...
typescript