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.
[Leetcode 208] Implement Trie (Prefix Tree)
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.
classTrie: def__init__(self, n): self.root = {} self.maxLen = n # max length of all numbers defadd_num(self, num): node = self.root # shift self.maxLen bits for shift inrange(self.maxLen, -1, -1): # get a bit from left to right val = 1if num & (1 << shift) else0
if val notin node: node[val] = {}
node = node[val] # mark the number node['*'] = num classSolution: deffindMaximumXOR(self, nums: List[int]) -> int: # get max length of all numbers' binary. e.g. bin(6)=0b110 max_len = len(bin(max(nums))) - 2
# build trie with number's binary trie = Trie(max_len) for num in nums: trie.add_num(num) #print(trie.root)
ans = 0
# for each num, find the number which can create max value with num using XOR for num in nums: node = trie.root for shift inrange(max_len, -1, -1): # get a bit from left to right val = 1if num & (1 << shift) else0
# try opposite bit if it's in trie to make it larger, otherwise use itself node = node[1-val] if1-val in node else node[val]
# calculate xor and save to answer ans = max(ans, num ^ node['*']) return ans
[Leetcode 1268] Search Suggestions System
You are given an array of strings products and a string searchWord.
Design a system that suggests at most three product names from products after each character of searchWord is typed. Suggested products should have common prefix with searchWord. If there are more than three products with a common prefix return the three lexicographically minimums products.
Return a list of lists of the suggested products after each character of searchWord is typed.
Example 1:
1 2 3 4 5
Input: products = ["mobile","mouse","moneypot","monitor","mousepad"], searchWord = "mouse" Output: [["mobile","moneypot","monitor"],["mobile","moneypot","monitor"],["mouse","mousepad"],["mouse","mousepad"],["mouse","mousepad"]] Explanation: products sorted lexicographically = ["mobile","moneypot","monitor","mouse","mousepad"]. After typing m and mo all products match and we show user ["mobile","moneypot","monitor"]. After typing mou, mous and mouse the system suggests ["mouse","mousepad"].
Example 2:
1 2 3
Input: products = ["havana"], searchWord = "havana" Output: [["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]] Explanation: The only word "havana" will be always suggested while typing the search word.
Constraints:
1 <= products.length <= 1000
1 <= products[i].length <= 3000
1 <= sum(products[i].length) <= 2 * 104
All the strings of products are unique.
products[i] consists of lowercase English letters.
1 <= searchWord.length <= 1000
searchWord consists of lowercase English letters.
Solution:
Brute force:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defsuggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]: res = [] products.sort() # ensure the lexicographical order of products
for i, c inenumerate(searchWord): curr = [] prefix = searchWord[:i+1] for prod in products: if prefix == prod[:i+1]: curr.append(prod) iflen(curr) == 3: break
defadd(self, word): node = self.root for c in word: if c notin node: node[c] = {} # create a child node {} node = node[c] # move down to the child node
# add word list to current node if'words'notin node: node['words'] = []
# add word to list since it goes through the current character iflen(node['words']) < 3: node['words'].append(word)
defsearch(self, prefix): node = self.root for c in prefix: if c notin node: return'' node = node[c]