For each prefix of the search word, we need to find up to three products that match that prefix in lexicographical order. By sorting products first, we guarantee that the first matching products we encounter are the lexicographically smallest. We then scan through all products for each prefix, collecting up to three matches.
i from 1 to m (length of searchWord):i characters match the current prefix.class Solution:
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
res = []
m = len(searchWord)
products.sort()
for i in range(m):
cur = []
for w in products:
if len(w) <= i:
continue
flag = True
for j in range(i + 1):
if w[j] != searchWord[j]:
flag = False
break
if flag:
cur.append(w)
if len(cur) == 3:
break
if not cur:
for j in range(i, m):
res.append([])
break
res.append(cur)
return resWhere is the total number of characters in the string array , is the length of the string , and is the average length of each word in the given string array.
Once products are sorted, all products sharing a prefix form a contiguous block. Instead of scanning all products for each prefix, we use binary search to find where this block starts. Since the prefix grows character by character, the start position can only move forward, so we keep track of it across iterations.
prefix as an empty string and start = 0.searchWord:prefix.prefix, starting from start.start to this position.start that have prefix as their prefix.class Solution:
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
res = []
m = len(searchWord)
products.sort()
prefix = []
start = 0
def binary_search(target, start):
l, r = start, len(products)
while l < r:
mid = l + (r - l) // 2
if products[mid] >= target:
r = mid
else:
l = mid + 1
return l
for i in range(m):
prefix.append(searchWord[i])
start = binary_search("".join(prefix), start)
cur = []
for j in range(start, min(start + 3, len(products))):
if products[j].startswith("".join(prefix)):
cur.append(products[j])
else:
break
res.append(cur)
return resWhere is the total number of characters in the string array , is the size of the array , is the length of the string , and is the average length of each word in the given string array.
This approach is identical to the previous one, but uses built-in binary search functions provided by the language. Functions like bisect_left in Python or lower_bound in C++ handle the binary search logic, making the code cleaner and less error-prone.
prefix as an empty string and start = 0.searchWord:prefix.prefix.prefix as their prefix.class Solution:
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
res = []
m = len(searchWord)
products.sort()
prefix = ""
start = 0
for i in range(m):
prefix += searchWord[i]
start = bisect_left(products, prefix, start)
cur = []
for j in range(start, min(start + 3, len(products))):
if products[j].startswith(prefix):
cur.append(products[j])
else:
break
res.append(cur)
return resWhere is the total number of characters in the string array , is the size of the array , is the length of the string , and is the average length of each word in the given string array.
Instead of binary searching for each prefix, we maintain a window [l, r] of valid products. As we process each character of the search word, we shrink the window by moving l forward past products that do not match at position i, and moving r backward past products that do not match. The first up to 3 products in the remaining window are our suggestions.
l = 0 and r = n - 1.i from 0 to m - 1 (each character in searchWord):l forward while products[l] is too short or has the wrong character at position i.r backward while products[r] is too short or has the wrong character at position i.[l, r].class Solution:
def suggestedProducts(self, products: List[str], searchWord: str) -> List[List[str]]:
res = []
products.sort()
l, r = 0, len(products) - 1
for i in range(len(searchWord)):
c = searchWord[i]
while l <= r and (len(products[l]) <= i or products[l][i] != c):
l += 1
while l <= r and (len(products[r]) <= i or products[r][i] != c):
r -= 1
res.append([])
remain = r - l + 1
for j in range(min(3, remain)):
res[-1].append(products[l + j])
return resWhere is the total number of characters in the string array , is the size of the array , is the length of the string , and is the average length of each word in the given string array.
The problem requires returning suggestions in lexicographical order. A common mistake is attempting to find matches without first sorting the products array. Without sorting, you cannot guarantee that the first three matching products are the lexicographically smallest ones.
When checking if a product matches the current prefix, you must verify that the product is long enough to contain the prefix. Accessing product[i] when product.length <= i causes an index out of bounds error. Always check the product length before comparing characters at a given position.
Rebuilding or recomputing the prefix string from scratch for each character of the search word leads to unnecessary overhead. Instead, incrementally build the prefix by appending one character at a time, and reuse the previous search position since matching products form a contiguous block in the sorted array.