Solving Leetcode Interviews in Seconds with AI: Implement Trie (Prefix Tree)
Introduction
In this blog post, we will explore how to solve the LeetCode problem "208" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
A trie (pronounced as "try") or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker. Implement the Trie class: Trie() Initializes the trie object. void insert(String word) Inserts the string word into the trie. boolean search(String word) Returns true if the string word is in the trie (i.e., was inserted before), and false otherwise. boolean startsWith(String prefix) Returns true if there is a previously inserted string word that has the prefix prefix, and false otherwise. Example 1: Input ["Trie", "insert", "search", "search", "startsWith", "insert", "search"] [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]] Output [null, null, true, false, true, null, true] Explanation Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // return True trie.search("app"); // return False trie.startsWith("app"); // return True trie.insert("app"); trie.search("app"); // return True Constraints: 1 <= word.length, prefix.length <= 2000 word and prefix consist only of lowercase English letters. At most 3 * 104 calls in total will be made to insert, search, and startsWith.
Explanation
- Trie Node Structure: Each node in the trie represents a character. The root node represents an empty string. Each node contains a dictionary (or array) of children nodes, where the keys are characters. Additionally, each node has a boolean flag to indicate if it represents the end of a valid word.
- Insertion, Search, and StartsWith:
inserttraverses the trie, creating new nodes as needed for characters in the word.searchtraverses the trie and returnsTrueonly if the word exists and the final node is a word-end.startsWithtraverses the trie and returnsTrueif the prefix exists (regardless of whether it forms a complete word). - Optimization: Using a dictionary for children nodes allows for efficient lookup of characters.
- Insertion, Search, and StartsWith:
- Runtime & Storage Complexity: O(m) for insert, search, and startsWith, where m is the key length. O(N * k) space, where N is the number of keys and k is the average key length.
Code
class Trie:
def __init__(self):
self.root = {}
def insert(self, word: str) -> None:
node = self.root
for char in word:
if char not in node:
node[char] = {}
node = node[char]
node['#'] = True # Mark end of word
def search(self, word: str) -> bool:
node = self.root
for char in word:
if char not in node:
return False
node = node[char]
return '#' in node # Check for end of word marker
def startsWith(self, prefix: str) -> bool:
node = self.root
for char in prefix:
if char not in node:
return False
node = node[char]
return True
# Your Trie object will be instantiated and called as such:
# trie = Trie()
# trie.insert(word)
# param_2 = trie.search(word)
# param_3 = trie.startsWith(prefix)