zoukankan      html  css  js  c++  java
  • 642. Design Search Autocomplete System

    package LeetCode_642
    
    import java.util.*
    import kotlin.collections.ArrayList
    import kotlin.collections.HashMap
    
    /**
     * 642. Design Search Autocomplete System
     * (Prime)
     * 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 3 historical hot sentences that have prefix the same as the part of sentence already typed.
    Here are the specific rules:
    1. The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before.
    2. 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).
    3. If less than 3 hot sentences exist, then just return as many as you can.
    4. 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.
     * */
    
    /*
    * solution: Trie + PriorityQueue
    * */
    class AutocompleteSystem constructor(sentences: Array<String>, times: Array<Int>) {
    
        var root: TrieNode? = null
        var perfix = ""
    
        init {
            root = TrieNode()
            for (i in sentences.indices) {
                add(sentences[i], times[i])
            }
        }
    
        private fun add(word: String, time: Int) {
            var cur = root
            for (ch in word) {
                var next = cur!!.children.get(ch)
                if (next == null) {
                    next = TrieNode()
                    cur.children.put(ch, next)
                }
                //establish root-children relationship
                cur = next
                cur.counts.put(word, cur.counts.getOrDefault(word, 0) + time)
            }
            cur?.isWord = true
        }
    
        class TrieNode {
            var children = HashMap<Char, TrieNode>()
            var counts = HashMap<String, Int>()
            var isWord = false
        }
    
        class Node(word_: String, count_: Int) {
            var word: String = ""
            var count = 0
    
            init {
                word = word_
                count = count_
            }
        }
    
        fun input(c: Char): List<String> {
            if (c == '#') {
                add(perfix, 1)
                perfix = ""
                return ArrayList()
            }
            perfix += c
            var cur = root
            for (ch in perfix) {
                val next = cur!!.children.get(ch)
                if (next == null) {
                    return ArrayList()
                } else {
                    cur = next
                }
            }
            val queue = PriorityQueue<Node> { a, b ->
                if (a.count == b.count) {
                    a.word.compareTo(b.word)
                } else {
                    b.count - a.count
                }
            }
            for (item in cur!!.counts) {
                queue.offer(Node(item.key, item.value))
            }
            val result = ArrayList<String>()
            var i = 0
            while (i < 3 && queue.isNotEmpty()) {
                result.add(queue.poll().word)
                i++
            }
            return result
        }
    }
    /**
     * Your AutocompleteSystem object will be instantiated and called as such:
     * AutocompleteSystem obj = new AutocompleteSystem(sentences, times);
     * List<String> param_1 = obj.input(c);
     */
  • 相关阅读:
    为何没有.aspx.designer.cs文件?
    ItemDataBound的用法
    DataList控件 属性全攻略
    给LinkButton添加href、target属性
    给文本框添加灰色提示文字
    转载::深入研究DataList分页方法
    WCF 第六章 序列化与编码 保留引用和循环引用
    WCF 第六章 序列化和编码之NetDataContractSerializer
    WCF 第六章 序列化与编码 比较WCF序列化选项
    WCF 第六章 序列化和编码 使用代理序列化类型
  • 原文地址:https://www.cnblogs.com/johnnyzhao/p/13939058.html
Copyright © 2011-2022 走看看