Let's design an autocomplete system. Imagine you are building the backend for a search bar that provides suggestions as the user types. Here's how it should work:
Data Storage: You have a dataset of sentences and their corresponding "hotness" scores (number of times the sentence has been searched). For example:
Input: The user enters characters one at a time. After each character, the system returns the top 3 "hottest" sentences starting with the current input. If two sentences have the same "hotness", sort them lexicographically (alphabetical order).
Output: A list of the top 3 matching sentences.
New Sentences: If the user types a sentence not already in the system and presses '#', the system adds the new sentence with a hotness of 1.
Example:
Assume the system is initialized with the above dataset.
Specific Requirements:
Implement the AutocompleteSystem
class with the following methods:
AutocompleteSystem(String[] sentences, int[] times)
: Initializes the system with the given sentences and their hotness scores.List<String> input(char c)
: Processes the next character c
typed by the user and returns the top 3 matching sentences.The sentences consist of lowercase English letters, spaces, and the special character '#'.
The hotness scores are non-negative integers.
Discuss the data structures you would use, the algorithms for efficient searching, and how you would handle edge cases such as empty input or no matching sentences.
Let's discuss how to design a search autocomplete system. This involves storing historical search data and providing suggestions as the user types. We'll cover a naive approach and then an optimized solution using a Trie data structure.
A straightforward approach would be to store all previously searched sentences and their frequencies. When the user types an input, we iterate through all stored sentences, check if the sentence starts with the input, and if it does, add it to the suggestions list. Sort the suggestions by frequency and return the top 3.
Stored data:
Input: "i "
The Trie (also known as a prefix tree) is a tree-like data structure that is very efficient for prefix-based search. Each node in the Trie represents a character, and the path from the root to a node represents a prefix. We can augment the Trie nodes to store frequency information.
class TrieNode:
def __init__(self):
self.children = {}
self.sentences = [] # List of (frequency, sentence) tuples
class AutocompleteSystem:
def __init__(self, sentences, times):
self.root = TrieNode()
self.keyword = ""
for i, sentence in enumerate(sentences):
self.add(sentence, times[i])
def add(self, sentence, time):
node = self.root
for char in sentence:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.sentences.append((-time, sentence)) # Store negative time for easier sorting
node.sentences.sort()
if len(node.sentences) > 3:
node.sentences.pop()
def search(self, c):
if c == '#':
self.add(self.keyword, 1)
self.keyword = ""
return []
self.keyword += c
node = self.root
for char in self.keyword:
if char not in node.children:
return []
node = node.children[char]
return [sentence for _, sentence in node.sentences]
#
as the end of sentence character.