Katkat

Build a Fuzzy Keyword Index

WorkdaySoftware Engineer · Onsite

Last updated

This problem tests your ability to design an efficient data structure for performing fuzzy keyword lookups using edit distance constraints on a static corpus of strings.

Problem Statement

You are tasked with building a search service that allows users to perform "fuzzy" lookups on a fixed dictionary of $N$ words. A query is considered a match if a word exists in the dictionary with an edit distance (Levenshtein distance) of at most $K=1$ from the query string.

Implement a class FuzzyIndex that optimizes for repeated query performance.

Requirements

  • __init__(dictionary): Preprocesses the list of unique words to enable fast lookups.
  • search(query): Returns a list of all words in the dictionary that have an edit distance of 0 or 1 from the query.

Constraints

  • Number of words $N$ is up to 50,000.
  • Maximum length of any word $L$ is 20.
  • Preprocessing time should be reasonable (e.g., under 5 seconds).
  • search should be significantly faster than iterating through all words.

Example

dictionary = ["apple", "apply", "banana", "pear"]
index = FuzzyIndex(dictionary)
index.search("appel")  # Returns ['apple']
index.search("apple")  # Returns ['apple', 'apply']
index.search("banan")  # Returns ['banana']

Edge Cases

  • Empty dictionary or empty query strings.
  • Queries that are much longer or shorter than any word in the dictionary.
  • Queries resulting in multiple matches (e.g., distance 1 for multiple dictionary words).

Hints

Hint 1

Consider that edit distance 1 involves either one deletion, one insertion, or one substitution.

Hint 2

For each word in the dictionary, can you pre-generate all possible strings that are exactly distance 1 away and store them in a hash map?

Hint 3

Alternatively, use a Trie to traverse the dictionary and prune the search space when the current edit distance exceeds your threshold.

Follow-up questions

  • How would you modify your solution if the threshold $K$ were increased to 2?
  • What are the memory trade-offs between pre-generating all distance-1 variations versus searching the Trie at runtime?
  • How would you handle a scenario where the dictionary is updated dynamically (words added/removed) rather than being static?