• LeetCode——设计搜索自动补全系统


    Q:
    为搜索引擎设计一个搜索自动补全系统。用户会输入一条语句(最少包含一个字母,以特殊字符 '#' 结尾)。除 '#' 以外用户输入的每个字符,返回历史中热度前三并以当前输入部分为前缀的句子。下面是详细规则:

    一条句子的热度定义为历史上用户输入这个句子的总次数。
    返回前三的句子需要按照热度从高到低排序(第一个是最热门的)。如果有多条热度相同的句子,请按照 ASCII 码的顺序输出(ASCII 码越小排名越前)。
    如果满足条件的句子个数少于 3,将它们全部输出。
    如果输入了特殊字符,意味着句子结束了,请返回一个空集合。
    你的工作是实现以下功能:

    构造函数:
    AutocompleteSystem(String[] sentences, int[] times): 这是构造函数,输入的是历史数据。 Sentences 是之前输入过的所有句子,Times 是每条句子输入的次数,你的系统需要记录这些历史信息。

    现在,用户输入一条新的句子,下面的函数会提供用户输入的下一个字符:
    List input(char c): 其中 c 是用户输入的下一个字符。字符只会是小写英文字母('a' 到 'z' ),空格(' ')和特殊字符('#')。输出历史热度前三的具有相同前缀的句子。

    样例 :
    操作 : AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2])
    系统记录下所有的句子和出现的次数:
    "i love you" : 5 次
    "island" : 3 次
    "ironman" : 2 次
    "i love leetcode" : 2 次
    现在,用户开始新的键入:

    输入 : input('i')
    输出 : ["i love you", "island","i love leetcode"]
    解释 :
    有四个句子含有前缀 "i"。其中 "ironman" 和 "i love leetcode" 有相同的热度,由于 ' ' 的 ASCII 码是 32 而 'r' 的 ASCII 码是 114,所以 "i love leetcode" 在 "ironman" 前面。同时我们只输出前三的句子,所以 "ironman" 被舍弃。

    输入 : input(' ')
    输出 : ["i love you","i love leetcode"]
    解释:
    只有两个句子含有前缀 "i "。

    输入 : input('a')
    输出 : []
    解释 :
    没有句子有前缀 "i a"。

    输入 : input('#')
    输出 : []
    解释 :
    用户输入结束,"i a" 被存到系统中,后面的输入被认为是下一次搜索。

    注释 :
    输入的句子以字母开头,以 '#' 结尾,两个字母之间最多只会出现一个空格。
    即将搜索的句子总数不会超过 100。每条句子的长度(包括已经搜索的和即将搜索的)也不会超过 100。
    即使只有一个字母,输出的时候请使用双引号而不是单引号。
    请记住清零 AutocompleteSystem 类中的变量,因为静态变量、类变量会在多组测试数据中保存之前结果。详情请看这里。

    A:使用两层 (HashMap) 存储句子和出现的次数。
    使用数组 (arr) 存储所有的句子和出现的次数,数组的每一项都是一个 (HashMap),每个 (HashMap) 存储相同首字母的所有句子。例如 (arr[0]) 表示所有以 ('a') 开头的所有句子的 (HashMap)
    在添加或查找string时,先使用第一层索引 (arr) 找出对应首字母的 (HashMap)

        class AutocompleteSystem {
            HashMap<String, Integer>[] arr;
    
            public AutocompleteSystem(String[] sentences, int[] times) {
                arr = new HashMap[26];
                for (int i = 0; i < 26; i++) {
                    arr[i] = new HashMap<>();
                }
                for (int i = 0; i < sentences.length; i++) {
                    int index = sentences[i].charAt(0) - 'a';
                    arr[index].put(sentences[i], times[i]);
                }
            }
    
            String cur_sent = "";
    
            public List<String> input(char c) {
                List<String> res = new ArrayList<>();
                if (c == '#') {
                    int index = cur_sent.charAt(0) - 'a';
                    arr[index].put(cur_sent, arr[index].getOrDefault(cur_sent, 0) + 1);
                    cur_sent = "";
                } else {
                    List<Pair<String, Integer>> list = new ArrayList<>();
                    cur_sent += c;
                    int index = cur_sent.charAt(0) - 'a';
                    for (String key : arr[index].keySet()) {
                        if (key.indexOf(cur_sent) == 0) {
                            list.add(new Pair<>(key, arr[index].get(key)));
                        }
                    }
                    list.sort((a, b) -> a.getValue() == b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue() - a.getValue());
                    if (list.size() <= 3) {
                        for (Pair<String, Integer> stringIntegerPair : list) {
                            res.add(stringIntegerPair.getKey());
                        }
                    } else {
                        for (int i = 0; i < 3; i++) {
                            res.add(list.get(i).getKey());
                        }
                    }
                }
                return res;
            }
        }
    
  • 相关阅读:
    o9.17,习题
    09.17,二维数组,地图
    09.15,一维数组,冒泡排序
    09.11 小兔 成兔问题
    09.01,学习习题
    FTPHelper
    Wpf发送接收 win32消息
    win32Helper
    xml 封装类
    C# 多进程安全
  • 原文地址:https://www.cnblogs.com/xym4869/p/12699169.html
Copyright © 2020-2023  润新知