1、题目描述
2、解题思路
本题其实考的是对数据结构的掌握。
先把输入的句子 sentences 按首字母分类存放。
a - z 总共有 26 个字母,因此创建一个数组,容量为 26,数组的元素为 HashMap,键为句子,值为输入的次数。
arr[0] 保存 ‘a’ 开头,arr[1] 保存 ‘b’ 开头,。。。,arr[25] 保存 ‘z’ 开头。
比如:“ababc” 出现了 5 次,则 arr[0] = {“ababc”, 5} (中括号表示 HashMap)
这样,当调用 input 方法时,如果不是结束字符,则直接根据已输入字符构成的句子 curSent 的首字符从 arr 数组中找。
比如,curSent = “zoon” ,那么我们直接从 arr[25] 中找匹配的句子,拿 curSent 遍历去找 arr[25] 中的所有句子,找出以 “zoon” 开头的句子存入 list 中。
接着对 list 进行排序,排序的依据是句子的 times,大在前,小在后。如果一样,则按照字典序。
最终返回的结果句子取 list 的前 3 个,不足 3 个则全部返回。
3、解题代码
class AutocompleteSystem {
// 数组的每一个元素都是一个 HashMap,key 为句子,value 为出现次数
// arr[0] 表示以字符 'a' 开头的句子
// arr[1] 表示以字符 'b' 开头的句子
// ...
// 以此类推,arr[25] 表示以字符 'z' 开头的句子
HashMap<String, Integer>[] arr;
String curSent = ""; // 用于存放句子
class Node {
Node(String st, int t) {
sentence = st;
times = t;
}
String sentence;
int times;
}
public AutocompleteSystem(String[] sentences, int[] times) {
arr = new HashMap[26];
// 初始化数组每一个元素的 HashMap
for (int i = 0; i < 26; i++) {
arr[i] = new HashMap<String, Integer>();
}
// 把句子分门别类放入 arr 中
for (int i = 0; i < sentences.length; i++) {
// 减去 'a' 表示减去 a 的 ascii 码,得到的就是数组的索引
arr[sentences[i].charAt(0) - 'a'].put(sentences[i], times[i]);
}
}
public List<String> input(char c) {
List<String> res = new ArrayList<>(); // 存放即将返回的补全的句子
if (c == '#') {
// 如果已经结束输入
// cur_sent 新存入历史记录中
// map.getOrDefault(cur_sent, 0) 表示如果 map 中没有 key 为 cur_sent 的元素,则新建一个 key 为 cur_sent 的元素,值为 0
arr[cur_sent.charAt(0) - 'a'].put(
cur_sent,
arr[cur_sent.charAt(0) - 'a'].getOrDefault(cur_sent, 0) + 1
);
cur_sent = "";
} else {
// 尚未结束输入
List<Node> list = new ArrayList<>(); // 存放所有可能的补全句子
cur_sent += c; // 待搜索的句子
for (String key : arr[cur_sent.charAt(0) - 'a'].keySet()) {
if (key.indexOf(cur_sent) == 0) {
// 如果 cur_sent 是 key 的前缀,则符合要求,添加到 list 中
list.add(new Node(key, arr[cur_sent.charAt(0) - 'a'].get(key)));
}
}
// 对 list 进行排序,如果 times 不相等,则 times 大的在前面
// 如果 times 相等,则按照字典序
list.sort((a, b) -> a.times == b.times ? a.sentence.compareTo(b.sentence) : b.times - a.times);
// 最多只需要三条句子,不够三条就有多少返回多少
for (int i = 0; i < Math.min(3, list.size()); i++) {
res.add(list.get(i).sentence);
}
}
return res;
}
}
/**
* Your AutocompleteSystem object will be instantiated and called as such:
* AutocompleteSystem obj = new AutocompleteSystem(sentences, times);
* List<String> param_1 = obj.input(c);
*/