[LeetCode] 642. Design Search Autocomplete System 设计搜索自动补全系统
Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). For each character they type except '#', you need to return the top 3historical hot sentences that have prefix the same as the part of sentence already typed. Here are the specific rules:
- The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before.
- The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first).
- If less than 3 hot sentences exist, then just return as many as you can.
- When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list.
Your job is to implement the following functions:
The constructor function:
AutocompleteSystem(String[] sentences, int[] times): This is the constructor. The input is historical data. Sentences is a string array consists of previously typed sentences. Times is the corresponding times a sentence has been typed. Your system should record these historical data.
Now, the user wants to input a new sentence. The following function will provide the next character the user types:
List<String> input(char c): The input c is the next character typed by the user. The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). Also, the previously typed sentence should be recorded in your system. The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed.
Example:
Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2])
The system have already tracked down the following sentences and their corresponding times: "i love you" : 5 times "island" : 3 times "ironman" : 2 times "i love leetcode" : 2 times
Now, the user begins another search:
Operation: input('i')
Output: ["i love you", "island","i love leetcode"]
Explanation:
There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". Also we only need to output top 3 hot sentences, so "ironman" will be ignored.
Operation: input(' ')
Output: ["i love you","i love leetcode"]
Explanation:
There are only two sentences that have prefix "i ".
Operation: input('a')
Output: []
Explanation:
There are no sentences that have prefix "i a".
Operation: input('#')
Output: []
Explanation:
The user finished the input, the sentence "i a" should be saved as a historical sentence in system. And the following input will be counted as a new search.
Note:
- The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words.
- The number of complete sentences that to be searched won't exceed 100. The length of each sentence including those in the historical data won't exceed 100.
- Please use double-quote instead of single-quote when you write test cases even for a character input.
- Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. Please see here for more details.
这道题让实现一个简单的搜索自动补全系统,当我们用谷歌或者百度进行搜索时,会有这样的体验,输入些单词,搜索框会弹出一些以你输入为开头的一些完整的句子供你选择,这就是一种搜索自动补全系统。根据题目的要求,补全的句子是按之前出现的频率排列的,高频率的出现在最上面,如果频率相同,就按字母顺序来显示。输入规则是每次输入一个字符,然后返回自动补全的句子,如果遇到井字符,表示完整句子结束。那么肯定需要一个 HashMap,建立句子和其出现频率的映射,还需要一个字符串 data,用来保存之前输入过的字符。在构造函数中,给了一些句子,和其出现的次数,直接将其加入 HashMap,然后 data 初始化为空字符串。在 input 函数中,首先判读输入字符是否为井字符,如果是的话,那么表明当前的 data 字符串已经是一个完整的句子,在 HashMap 中次数加1,并且 data 清空,返回空集。否则的话将当前字符加入 data 字符串中,现在就要找出包含 data 前缀的前三高频句子了,使用优先队列来做,设计的思路是,始终用优先队列保存频率最高的三个句子,应该把频率低的或者是字母顺序大的放在队首,以便随时可以移出队列,所以应该是个最小堆,队列里放句子和其出现频率的 pair 对儿,并且根据其频率大小进行排序,要重写优先队列的 comparator。然后遍历 HashMap 中的所有句子,首先要验证当前 data 字符串是否是其前缀,没啥好的方法,就逐个字符比较,用标识符 matched,初始化为 true,如果发现不匹配,则 matched 标记为 false,并 break 掉。然后判断如果 matched 为 true 的话,说明 data 字符串是前缀,那么就把这个 pair 加入优先队列中,如果此时队列中的元素大于三个,那把队首元素移除,因为是最小堆,所以频率小的句子会被先移除。然后就是将优先队列的元素加到结果 res 中,由于先出队列的是频率小的句子,所以要加到结果 res 的末尾,参见代码如下:
class AutocompleteSystem {
public:
AutocompleteSystem(vector<string> sentences, vector<int> times) {
for (int i = ; i < sentences.size(); ++i) {
freq[sentences[i]] += times[i];
}
data = "";
}
vector<string> input(char c) {
if (c == '#') {
++freq[data];
data = "";
return {};
}
data.push_back(c);
auto cmp = [](pair<string, int>& a, pair<string, int>& b) {
return a.second > b.second || (a.second == b.second && a.first < b.first);
};
priority_queue<pair<string, int>, vector<pair<string, int>>, decltype(cmp) > q(cmp);
for (auto f : freq) {
bool matched = true;
for (int i = ; i < data.size(); ++i) {
if (data[i] != f.first[i]) {
matched = false;
break;
}
}
if (matched) {
q.push(f);
if (q.size() > ) q.pop();
}
}
vector<string> res(q.size());
for (int i = q.size() - ; i >= ; --i) {
res[i] = q.top().first; q.pop();
}
return res;
}
private:
unordered_map<string, int> freq;
string data;
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/642
类似题目:
参考资料:
https://leetcode.com/problems/design-search-autocomplete-system/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 642. Design Search Autocomplete System 设计搜索自动补全系统的更多相关文章
- [LeetCode] Design Search Autocomplete System 设计搜索自动补全系统
Design a search autocomplete system for a search engine. Users may input a sentence (at least one wo ...
- StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程)
@ 目录 StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程) 一.下载ELK的安装包上传并解压 1.Elasticsearch下载 2.Logstash下载 3.Kibana ...
- Design Search Autocomplete System
Design a search autocomplete system for a search engine. Users may input a sentence (at least one wo ...
- autocomplete实现联想输入,自动补全
jQuery.AutoComplete是一个基于jQuery的自动补全插件.借助于jQuery优秀的跨浏览器特性,可以兼容Chrome/IE/Firefox/Opera/Safari等多种浏览器. 特 ...
- WinForm AutoComplete 输入提示、自动补全
一.前言 又临近春节,作为屌丝的我,又要为车票发愁了.记得去年出现了各种12306的插件,最近不忙,于是也着手自己写个抢票插件,当是熟悉一下WinForm吧.小软件还在开发中,待完善后,也写篇博客与大 ...
- 仿Google首页搜索自动补全
仿Google自动补全,实现细节: 后台是简单的servlet(其实就是负责后台处理数据交互的,没必要非跌用个struts...什么的) 传输介质:xml 使用jQuery js框架 功能实现: 如果 ...
- jquery input 搜索自动补全、typeahead.js
最近做个一个功能需要用到自动补全,然后在网上找了很久,踩了各种的坑 最后用typeahead.js这个插件,经过自己的测试完美实现 使用方法:在页面中引入jquery.jquery.typeahead ...
- 第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—用Django实现搜索的自动补全功能 elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.e ...
- 四十七 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.elastic.co/guide/en/elasticsearch/reference/current/se ...
随机推荐
- IDEA设置外部比对工具Beyond Compare
设置IDEA使用外部的比对工具,比如Beyond Compare,其实很简单,但是可能好几年才会设置一次,比如换工作的时候,所以记录下来 可以通过菜单File-Settings 或者直接快捷键ctrl ...
- JWT简要说明
什么是JWT? JSON Web Token (JWT) 是一种开放标准 (RFC 7519) 定义了一种用于安全传输的紧凑.自包含(注:或自说明) 的Json结构, 被传输的信息可以通过JWT内容中 ...
- 解决微信浏览器缓存站点入口文件(IIS部署Vue项目)
最近开发的微信公众号项目中(项目采用Vue + Vux 构建,站点部署在IIS8.5上),遇到个非常奇葩的问题,发布站点内容后,通过微信打开网址发现是空白页面(后来验证是微信浏览器缓存了入口文件-in ...
- MySQL分析数据运行状态利器【show full processlist】
原文地址:https://www.cnblogs.com/shihuc/p/8733460.html 今天的主角是: SHOW [FULL] PROCESSLIST show full process ...
- CentOS 8 换源,设置dnf / yum镜像
aliyun更新了centos8的说明 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos- ...
- sequelize-auto生成sequelize所有模型
sequelize是node最受欢迎的orm库,普遍使用 Promise. 意味着所有异步调用可以使用 ES2017 async/await 语法. 快速入门地址:https://github.com ...
- 修改VisualStudio的智能提示字体大小
最近换了一个高分辨率显示器,便觉得VisualStudio的字体过小了,虽然VisualStudio换字体还比较简单,大部分位置的字体基本上很顺利的就换掉了,然而一直找不到智能提示的字体所在位置,放狗 ...
- Linux文件共享服务 FTP,NFS 和 Samba
Linux 系统中,存储设主要有下面几种: DAS DAS 指 Direct Attached Storage,即直连附加存储,这种设备直接连接到计算机主板总线上,计算机将其识别为一个块设备,例如常见 ...
- 手写instanceof (详解原型链) 和 实现绑定解绑和派发的事件类
A instanceof B 是判断 A 是否继承自B,是返回true, 否返回false 再精确点就是判断B 是否 再 A 的 原型链上, 什么是原型链,举个例子: 我们定 ...
- 汇编指令之JMP,CALL,RET(修改EIP的值!!!)
简单介绍了,JMP指令按市面上的意思来说是跳转到指定地址,但我这里不这么说,JMP, CALL, RET三个指令均为修改EIP值的指令,EAX, ECX, EBX, EDX, ESP, EBP, ES ...