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.
Test Cases
Example 1:
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:
Input: products = ["havana"], searchWord = "havana"
Output: [["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]]
Example 3:
Input: products = ["havana"], searchWord = "tatiana"
Output: [[],[],[],[],[],[],[]]
Example 4:
Input: products = ["bags","baggage","banner","box","cloths"], searchWord = "bags"
Output: [["baggage","bags","banner"],["baggage","bags","banner"],["baggage","bags"],["bags"]]
Solution
class Solution {
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
TrieNode root = new TrieNode();
for(String product: products) {
root.add(product);
}
int n = searchWord.length();
List<List<String>> res = new ArrayList<>();
for(int i=0; i<n; i++) {
char c = searchWord.charAt(i);
int pos = c - 'a';
List<String> list = new ArrayList<>();
if (root != null && root.children[pos] != null) {
PriorityQueue<String> pq = root.children[pos].top;
while(!pq.isEmpty()) list.add(0, pq.poll());
pq.addAll(list);
}
res.add(list);
if (root == null) continue;
root = root.children[pos];
}
return res;
}
}
class TrieNode {
PriorityQueue<String> top;
TrieNode[] children;
boolean isEndWord;
static int MAX_SIZE = 3;
TrieNode() {
top = new PriorityQueue<>((a,b) -> b.compareTo(a));
children = new TrieNode[26];
isEndWord = false;
}
public void add(String s) {
TrieNode root = this;
int n = s.length();
for(int i=0; i<n; i++) {
char c = s.charAt(i);
int pos = c - 'a';
if (root.children[pos] == null) {
root.children[pos] = new TrieNode();
}
PriorityQueue<String> pq = root.children[pos].top;
if (pq.size() < MAX_SIZE) pq.offer(s);
else {
if (pq.peek().compareTo(s) > 0) {
pq.poll();
pq.offer(s);
}
}
root.children[pos].top = pq;
root = root.children[pos];
}
root.isEndWord = true;
}
}