From 40f6ce9403d1d15b1a21cf69dd340c3c901e5968 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Thu, 5 Mar 2020 21:45:25 +0800 Subject: [PATCH] add 208. Implement Trie (Prefix Tree) :beer: --- README.md | 1 + .../208. Implement Trie (Prefix Tree).md | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 solutions/208. Implement Trie (Prefix Tree).md diff --git a/README.md b/README.md index 5e2b605..6b3a02f 100644 --- a/README.md +++ b/README.md @@ -166,6 +166,7 @@ My LeetCode solutions with Chinese explanation. 我的LeetCode中文题解。 | 205 |[Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/205.%20Isomorphic%20Strings.md)|Easy| | | 206 |[Reverse Linked List](https://leetcode.com/problems/reverse-linked-list)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/206.%20Reverse%20Linked%20List.md)|Easy| | | 207 |[Course Schedule](https://leetcode.com/problems/course-schedule/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/207.%20Course%20Schedule.md)|Medium| | +| 208 |[208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/)|[C++](solutions/208.%20Implement%20Trie%20(Prefix%20Tree).md)|Medium| | | 209 |[Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/209.%20Minimum%20Size%20Subarray%20Sum.md)|Medium| | | 210 |[Course Schedule II](https://leetcode.com/problems/course-schedule-ii/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/210.%20Course%20Schedule%20II.md)|Medium| | | 213 |[House Robber II](https://leetcode.com/problems/house-robber-ii/)|[C++](https://github.com/ShusenTang/LeetCode/blob/master/solutions/213.%20House%20Robber%20II.md)|Medium| | diff --git a/solutions/208. Implement Trie (Prefix Tree).md b/solutions/208. Implement Trie (Prefix Tree).md new file mode 100644 index 0000000..57e6197 --- /dev/null +++ b/solutions/208. Implement Trie (Prefix Tree).md @@ -0,0 +1,82 @@ +# [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) + +# 思路 + +要求实现一个字典树(Trie),又称为前缀树(Prefix Tree),字典树是一种很实用的数据结构。 + +字典树主要有如下三点性质: + +1. 根节点不包含字符,除根节点外每个节点只包含一个字符。 +2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 +3. 每个节点的所有子节点包含的字符串不相同。 + +如何存储孩子,一般有三种方法: +1、对每个结点开一个字母集大小的数组,对应的下标是儿子所表示的字母,内容则是这个儿子对应的位置(例如指向这个儿子的指针); +2、每个结点挂一个链表(或一个动态增长的数组),按一定顺序记录所有儿子; +3、使用左儿子右兄弟表示法记录这棵树。 + +三种方法,各有特点。第一种易实现,但实际的空间要求较大;第二种,较易实现,空间要求相对较小,但比较费时;第三种,空间要求最小,但相对费时且不易写。 + +由于题目说了只可能是小写字母,所以字母集大小就为26,下面代码我们就按照方法一来写。 + +另外在实现节点类时需要加一个bool型的属性`is_last_letter`,代表这个字母是否是某个单词的结尾。 + +# C++ +``` C++ +struct TrieNode{ + bool is_last_letter; // 是否是某个单词的结尾 + char letter; + vectornext; // 孩子们 + TrieNode(char cc): is_last_letter(false), letter(cc), + next(vector(26, NULL)){} +}; + +class Trie { +private: + TrieNode *root; + +public: + /** Initialize your data structure here. */ + Trie() { + root = new TrieNode('\0'); // 根节点不包含字符 + root -> is_last_letter = true; + } + + /** Inserts a word into the trie. */ + void insert(string word) { + if(word.empty()) return; + TrieNode *pre = root, *p = NULL; + for(int i = 0; i < word.size(); i++){ + p = (pre -> next)[word[i] - 'a']; + if(!p){ // 没找到, 插入即可 + p = new TrieNode(word[i]); + (pre -> next)[word[i] - 'a'] = p; + } + pre = p; + } + p -> is_last_letter = true; + } + + // 返回word最后一个字母对应的在树中的节点指针 + TrieNode *final_char(string word){ + TrieNode *pre = root, *p = NULL; + for(int i = 0; i < word.size(); i++){ + p = (pre -> next)[word[i] - 'a']; + if(!p) return NULL; + pre = p; + } + return p; + } + + /** Returns if the word is in the trie. */ + bool search(string word) { + TrieNode *tmp = final_char(word); + return tmp && tmp -> is_last_letter; + } + + /** Returns if there is any word in the trie that starts with the given prefix. */ + bool startsWith(string prefix) { + return final_char(prefix) != NULL; + } +}; +``` \ No newline at end of file