1268. Search Suggestions System
解题思路一
本题要求我们实现一个搜索推荐系统,要求输入每一个字符都要展示前三个搜索结果(字典序排序)
这种逐个字符搜索的题目很适合使用 字典树 来求解,对于字典树中任意一个 node 节点,从根节点到它的字符串称为 prefix
另外,因为要逐个展示搜索结果,所以我们需要额外使用一个优先队列来保存三个以当前 prefix 为开头的字符串
C++
// 字典树结构
struct Trie {
unordered_map<char, Trie*> child;
priority_queue<string> words;
};
class Solution {
public:
void addWord(Trie* root, const string& word) {
Trie* cur = root;
for(const char& c : word) {
if(!cur->child.count(c)) {
cur->child[c] = new Trie();
}
cur = cur->child[c];
// 额外维护一个优先队列保存当前 prefix 的前三个字符串
cur->words.push(word);
if(cur->words.size() > 3) {
cur->words.pop();
}
}
}
vector<vector<string>> suggestedProducts(vector<string>& products, string searchWord) {
Trie* root = new Trie();
for(const string& word: products) {
addWord(root, word);
}
vector<vector<string>> ans;
Trie* cur = root;
// 标记字典树的结尾
bool flag = false;
for(const char& c: searchWord) {
if(flag || !cur->child.count(c)) {
ans.push_back({});
flag = true;
} else {
cur = cur->child[c];
vector<string> selects;
while(!cur->words.empty()) {
selects.push_back(cur->words.top());
cur->words.pop();
}
reverse(selects.begin(), selects.end());
ans.push_back(move(selects));
}
}
return ans;
}
};
解题思路二
当然,因为题目是需要我们找出限定范围内的 products,所以我们可以通过排序+缩小窗口的思路来进一步降低复杂度
步骤如下:
- 先对 products 按照字典序排序
- 用两个下标 left,right 分别指向排序后 products 的头尾
- 对于每一个 searchWord 的字符,我们需要判断 products 中相对位置字符的大小,更新 left 与 right
- 把确定范围的前三个放入返回的数组 res 中
- 重复第三步,直到遍历完所有的 searchWord 字符
- 最后返回 res
Javascript
/**
* @param {string[]} products
* @param {string} searchWord
* @return {string[][]}
*/
var suggestedProducts = function (products, searchWord) {
const sLen = searchWord.length
const pLen = products.length
products.sort()
let left = 0
let right = pLen - 1
const res = []
for (let i = 0; i < sLen; i++) {
const temp = []
while (left <= right && products[left].charAt(i) < searchWord[i]) {
left++
}
while (right >= 0 && products[right].charAt(i) > searchWord[i]) {
right--
}
for (let j = 0; j < 3 && (left + j) <= right; j++) {
temp.push(products[left + j])
}
res.push(temp)
}
return res
};
复杂度分析
M 代表 searchWord 的字符长度;n 代表 products 的长度;l 代表 products 中字符串的平均长度
时间
排序:O(nlogn * l)
双指针窗口遍历:O(n)
searchWord 遍历:O(m)
总复杂度:O(nlogn * l)
空间
O(n)