编程语言
首页 > 编程语言> > [LeetCode]642. Design Search Autocomplete System(JavaScript解法)

[LeetCode]642. Design Search Autocomplete System(JavaScript解法)

作者:互联网

题目描述

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 '#').

You are given a string array sentences and an integer array times both of length n where sentences[i] is a previously typed sentence and times[i] is the corresponding number of times the sentence was typed. For each input character except '#', return the top 3 historical hot sentences that have the same prefix as the part of the sentence already typed.

Here are the specific rules:

Implement the AutocompleteSystem class:

Example 1:

Input
["AutocompleteSystem", "input", "input", "input", "input"]
[[["i love you", "island", "iroman", "i love leetcode"], [5, 3, 2, 2]], ["i"], [" "], ["a"], ["#"]]
Output
[null, ["i love you", "island", "i love leetcode"], ["i love you", "i love leetcode"], [], []]

Explanation
AutocompleteSystem obj = new AutocompleteSystem(["i love you", "island", "iroman", "i love leetcode"], [5, 3, 2, 2]);
obj.input("i"); // return ["i love you", "island", "i love leetcode"]. 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.
obj.input(" "); // return ["i love you", "i love leetcode"]. There are only two sentences that have prefix "i ".
obj.input("a"); // return []. There are no sentences that have prefix "i a".
obj.input("#"); // return []. 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.

 Constraints:

思路分析

搜索自动补全设计题。

在AutocompleteSystem类中,我们需要 1: 存储历史搜索记录和其对映热度的映射;2: 用户输入#号前所有输入内容的记录;3. 所有符合匹配和排序规则的候选句子优先级队列 这3个变量来完成自动补全的逻辑。可以用Map和Array来实现这些数据结构。

数据结构定义好之后,再来看用户input操作时需要实现的逻辑:

  1. 若用户输入“#”,表明一个完整句子结束。此时:

    2. 若用户输入非“#”号:

这里需要再另外写两个工具类,首先是优先级队列的插入操作。因为js中没有priority_queue或是heap数据结构,所以这里用数组+二分法+插入排序来实现这个功能。先根据热度大小进行排序,找到从左到右数第一个 <= 要插入的句子的热度的数组下标index。如果index处的句子热度和要插入的句子热度相等,再比较ASCII码。

另一个是检查输入的字符串和句子是否匹配。可以用正则表达式+字符串test方法,也可以直接for循环一位一位比较,有一位不匹配就break返回false。(两种代码提交后发现for循环进行匹配runtime更短)

代码示例(Js)

这道题思路比较清晰,相对而言不是很复杂。不过网上没大看到js解法的solution,所以这里用js写一下代码示例:

 1 /**
 2  * @param {string[]} sentences
 3  * @param {number[]} times
 4  */
 5 var AutocompleteSystem = function(sentences, times) {
 6     this.historySearch = new Map(); // 历史搜索内容&热度 映射表
 7     sentences.forEach((sentence, index) => {
 8         this.historySearch.set(sentence, times[index]);
 9     });
10     this.inputData = []; // 用户输入的字符串
11     this.queue = []; // 优先级队列
12 };
13 
14 /** 
15  * @param {character} c
16  * @return {string[]}
17  */
18 AutocompleteSystem.prototype.input = function(c) {
19     if(c == '#') {
20         // 更新搜索历史
21         let finalSentence = this.inputData.join('');
22         let times = this.historySearch.has(finalSentence) ? this.historySearch.get(finalSentence) : 0;
23         this.historySearch.set(finalSentence, times + 1);
24         
25         this.inputData = [];
26         this.queue = [];
27         return [];
28     }
29     if(this.inputData.length == 0) {
30         for(let [sentence, times] of this.historySearch) {
31             if(this.isMatch(sentence, c)) {
32                 this.updateQueue([sentence, times]);
33             }
34         }
35         this.inputData.push(c);
36     }
37     else {   
38         this.inputData.push(c);
39         this.queue = this.queue.filter((item) => this.isMatch(item[0], this.inputData.join('')));
40     }
41     let result = [];
42     for(let i = 0; i < this.queue.length; i++) {
43         result.push(this.queue[i][0]);
44         if(result.length == 3) break;
45     }
46     return result;
47 };
48 
49 // 向优先级队列中插入新的元素(binary search + 插入排序)
50 AutocompleteSystem.prototype.updateQueue = function(pair) {
51     let left = 0, right = this.queue.length;
52     while(left < right) {
53         let middle = Math.floor((left + right) / 2);
54         // 用热度进行比较
55         if(this.queue[middle][1] > pair[1]) {
56             left = middle + 1;
57         }
58         else {
59             right = middle;
60         }
61     }
62     // 热度相同根据ASCII码进行比较
63     while(right < this.queue.length && this.queue[right][1] == pair[1]) {
64         if(pair[0] < this.queue[right][0]) break;
65         right++;
66     }
67     this.queue.splice(right, 0, pair);
68 };
69 
70 // 判断input是否和当前sentence匹配
71 AutocompleteSystem.prototype.isMatch = function(sentence, prefix) {
72     // let expression = new RegExp("^" + prefix);
73     // return expression.test(sentence);
74     for(let i = 0; i < prefix.length; i++) {
75         if(prefix[i] != sentence[i]) return false;
76     }
77     return true;
78 };
79 
80 /** 
81  * Your AutocompleteSystem object will be instantiated and called as such:
82  * var obj = new AutocompleteSystem(sentences, times)
83  * var param_1 = obj.input(c)
84  */

标签:Search,love,sentence,JavaScript,System,times,queue,sentences,input
来源: https://www.cnblogs.com/barryyeee/p/15358708.html