题目
解法1:trie
把products里面的所有单词建立成一个trie,每个trie节点下面有一个word list,代表到这个节点为止的prefix,有哪些单词满足条件.然后就遍历searchword即可
class TrieNode:
def __init__(self):
self.childs = {}
self.words = []
class Solution:
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
products.sort()
root = TrieNode()
for prod in products:
tmp_root = root
for c in prod:
if c not in tmp_root.childs:
tmp_root.childs[c] = TrieNode()
tmp_root.childs[c].words.append(prod)
tmp_root = tmp_root.childs[c]
tmp_root = root
ans = []
for i,c in enumerate(searchWord):
if c not in tmp_root.childs:
for _ in range(len(searchWord)-i):
ans.append([])
return ans
# ans.append(sorted(tmp_root.childs[c].words)[:3])
ans.append(tmp_root.childs[c].words[:3])
tmp_root = tmp_root.childs[c]
return ans
时间复杂度:O(nlogn) + O(nl), 前半部分来自排序,后半部分来自trie的建立,建立trie的复杂度是O(w*l),w为单词个数,l为单词平均长度,每个单词需要查询l次
解法2:二分搜索
- 把product排好序
- 按照prefix去搜索products的位置,也就是这个位置之前都比prefix小,右边都大于等于prefix,答案就只有可能从这个index右边的三个位置中产生,因为如果右边的这三个单词都不对的话,在更右边的就更不对了
class Solution:
def binary_search(self,products,prefix):
l = 0
r = len(products)
if products[l] >= prefix:
return -1
while l+1<r:
mid = l + (r-l)//2
# print(mid)
if products[mid] < prefix:
l = mid
else:
r = mid
return l
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
products.sort()
prefix = ""
ans = []
# print(products)
for c in searchWord:
tmp_ans = []
prefix += c
ind = self.binary_search(products,prefix)
for i in range(ind+1,min(len(products),ind+4)):
if products[i].startswith(prefix):
tmp_ans.append(products[i])
ans.append(tmp_ans)
return ans
# self.binary_search(products,'mou')
时间复杂度:O(m*log(n)*m),m为searchword的长度,n为products的长度,后面的m是考虑到字符串的比较