# 0642. Design Search Autocomplete System ###### tags: `Leetcode` `Hard` `Trie` `Design` Link: https://leetcode.com/problems/design-search-autocomplete-system/description/ ## 思路 主要是考察trie 但在trie的基础上 由于我们需要知道每个node都有哪些字符串 以及我们需要知道这个node的所有字符串里面出现频率最高的三个 所以我们给每个TrieNode都加上一个set来存当下node里应该有哪些word ```add()```函数不用多说 就是把字符串加到trie里面 ```input()```函数由于每次出现'#'才代表换了一个input 所以我们其实不需要每次输入一个字符 都拿当前的整个```input```字串去trie里面找现在搜到了哪个node 我们可以加一个currnode表示我们现在的位置 新的char来了我们可以接着currnode往下找 只要找一层就行了 这就是为什么我们需要在```add()```首尾都把```curr```设成```root``` 加了一个```blank```变量是因为如果搜到某一个点断掉了 也就是返回的ans是空的list 我们就不会往下再搜下一层 也就是保持```curr```不变 这时候我们可以把```blank```设成```true``` 这样只要不换input 都会返回空list ## Code ```java= class AutocompleteSystem { class TrieNode{ TrieNode[] children = new TrieNode[128]; Set<String> words; } TrieNode root = new TrieNode(); TrieNode curr = root; Map<String, Integer> count; public AutocompleteSystem(String[] sentences, int[] times) { int n = sentences.length; count = new HashMap<>(); for(int i=0; i<n; i++){ count.put(sentences[i], times[i]); add(sentences[i]); } } private void add(String sentence){ curr = root; for(int i=0; i<sentence.length(); i++){ char c = sentence.charAt(i); if(curr.children[c]==null) curr.children[c] = new TrieNode(); curr = curr.children[c]; if(curr.words==null) curr.words = new HashSet<>(); curr.words.add(sentence); } curr = root; } boolean blank = false; StringBuilder input = new StringBuilder(); public List<String> input(char c) { List<String> ans = new ArrayList<>(); if(c=='#'){ curr = root; blank = false; String s = input.toString(); add(s); count.put(s, count.getOrDefault(s,0)+1); input.setLength(0); return ans; } input.append(c); if(blank) return ans; if(curr.children[c]==null){ blank = true; return ans; } else{ curr = curr.children[c]; Queue<String> pq = new PriorityQueue<>((a,b)->(count.get(b)==count.get(a)?(b.compareTo(a)):(count.get(a)-count.get(b)))); for(String s:curr.words){ pq.add(s); if(pq.size()>3) pq.poll(); } while(!pq.isEmpty()){ ans.add(0, pq.poll()); } } return ans; } } ```