1268. 搜索推荐系统
1268. 搜索推荐系统
🟠 🔖 字典树
数组
字符串
二分查找
排序
堆(优先队列)
🔗 力扣
LeetCode
题目
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 ofsearchWord
is typed.
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"]]
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 * 10^4
- All the strings of
products
are unique. products[i]
consists of lowercase English letters.1 <= searchWord.length <= 1000
searchWord
consists of lowercase English letters.
题目大意
给你一个产品数组 products
和一个字符串 searchWord
,products
数组中每个产品都是一个字符串。
请你设计一个推荐系统,在依次输入单词 searchWord
的每一个字母后,推荐 products
数组中前缀与 searchWord
相同的最多三个产品。如果前缀相同的可推荐产品超过三个,请按字典序返回最小的三个。
请你以二维列表的形式,返回在输入 searchWord
每个字母后相应的推荐产品的列表。
示例 1:
输入: products = ["mobile","mouse","moneypot","monitor","mousepad"], searchWord = "mouse"
输出:[
["mobile","moneypot","monitor"],
["mobile","moneypot","monitor"],
["mouse","mousepad"],
["mouse","mousepad"],
["mouse","mousepad"]
]
解释: 按字典序排序后的产品列表是 ["mobile","moneypot","monitor","mouse","mousepad"]
输入 m 和 mo,由于所有产品的前缀都相同,所以系统返回字典序最小的三个产品 ["mobile","moneypot","monitor"]
输入 mou, mous 和 mouse 后系统都返回 ["mouse","mousepad"]
示例 2:
输入: products = ["havana"], searchWord = "havana"
输出:[["havana"],["havana"],["havana"],["havana"],["havana"],["havana"]]
示例 3:
输入: products = ["bags","baggage","banner","box","cloths"], searchWord = "bags"
输出:[["baggage","bags","banner"],["baggage","bags","banner"],["baggage","bags"],["bags"]]
示例 4:
输入: products = ["havana"], searchWord = "tatiana"
输出:[[],[],[],[],[],[],[]]
提示:
1 <= products.length <= 1000
1 <= Σ products[i].length <= 2 * 10^4
products[i]
中所有的字符都是小写英文字母。1 <= searchWord.length <= 1000
searchWord
中所有字符都是小写英文字母。
解题思路
对所有产品进行字典序排序。
构建字典树:
- 插入每个产品到字典树中。
- 同时在每个节点维护一个最多 3 个的候选列表。
搜索前缀:
- 遍历
searchWord
的每个字符,在字典树中查找对应节点。 - 返回节点中的候选列表。
- 遍历
返回结果:
- 将每个前缀对应的候选列表加入结果。
复杂度分析
- 时间复杂度:
O(n * L + m)
,其中L
是平均字符串长度,n
是products
的长度,m
是搜索字符串的长度。- 构建字典树:每个字符串插入
O(L)
,复杂度为O(n * L)
。 - 搜索:遍历
searchWord
的每个字符O(m)
,每次查找候选列表O(3)
,复杂度为O(m)
。 - 总复杂度:
O(n * L + m)
。
- 构建字典树:每个字符串插入
- 空间复杂度:
O(n * L)
,字典树占用的空间。
代码
/**
* @param {string[]} products
* @param {string} searchWord
* @return {string[][]}
*/
var suggestedProducts = function (products, searchWord) {
// 对 products 进行字典序排序
products.sort();
// 构建字典树
let dict = {};
for (let word of products) {
let cur = dict;
for (let char of word) {
if (!cur[char]) {
cur[char] = { suggest: [] };
}
cur = cur[char];
if (cur.suggest.length < 3) {
cur.suggest.push(word);
}
}
cur.isEnd = true;
}
// 搜索前缀
let res = [],
cur = dict;
for (let char of searchWord) {
if (cur) {
cur = cur[char];
}
res.push(cur ? cur.suggest : []);
}
return res;
};