给你一个产品数组 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
中所有字符都是小写英文字母。
class Solution {
/**
* 这个方法用于返回每个前缀的建议产品列表。
* @param products 传入的产品列表
* @param searchWord 搜索词
* @return 每个前缀的建议产品列表
*/
public List<List<String>> suggestedProducts(String[] products, String searchWord) {
// 先按字典序对产品数组进行排序
Arrays.sort(products);
// 创建一个列表来存储每个前缀的建议产品
List<List<String>> ls = new ArrayList<>();
// 遍历搜索词的每个前缀
for (int i = 1; i <= searchWord.length(); ++i) {
// 获取当前前缀
String s = searchWord.substring(0, i);
// 创建一个列表来存储符合当前前缀的产品
List<String> l1 = new ArrayList<>();
// 遍历所有产品
for (String str : products) {
// 如果产品以当前前缀开始,则将其添加到列表中
if (str.startsWith(s)) {
l1.add(str);
}
// 如果列表中已经有3个产品,则停止添加更多产品
if (l1.size() == 3) {
break;
}
}
// 将当前前缀的建议产品列表添加到最终结果列表中
ls.add(l1);
}
// 返回每个前缀的建议产品列表
return ls;
}
}
解题思路
-
排序:
- 首先对产品列表进行字典序排序。排序后的产品列表使得我们可以更高效地找到以某个前缀开头的前几个产品。
-
遍历前缀:
- 遍历搜索词的所有可能前缀。从长度为1开始,逐渐增加到搜索词的全长。在每次迭代中,取出当前的前缀(
s
)。
- 遍历搜索词的所有可能前缀。从长度为1开始,逐渐增加到搜索词的全长。在每次迭代中,取出当前的前缀(
-
筛选产品:
- 对于每个前缀,通过遍历排序后的产品列表来找出所有以当前前缀开始的产品。
- 将符合条件的产品添加到一个临时列表(
l1
)中。
-
限制结果数量:
- 如果临时列表的大小达到3,则停止对更多产品的搜索。这是因为我们只需要返回最多3个建议产品。
-
保存结果:
- 将每个前缀的建议产品列表添加到最终结果列表(
ls
)中。
- 将每个前缀的建议产品列表添加到最终结果列表(
-
返回结果:
- 返回包含所有前缀及其对应建议产品的列表。
时间复杂度
- 排序:
O(N log N)
,其中N
是产品数组的长度。 - 遍历和筛选:
O(N * M)
,其中N
是产品数组的长度,M
是搜索词的长度。每次遍历最多需要扫描N
个产品。
总的时间复杂度是 O(N log N + N * M)
。这个复杂度是可以接受的,特别是在处理较大的产品列表时。