【LeetCode】前缀树 trie(共14题)
【208】Implement Trie (Prefix Tree) (2018年11月27日)
实现基本的 trie 树,包括 insert, search, startWith 操作等 api。
题解:《程序员代码面试指南》chp5, 最后一题。 里面讲了怎么实现。这个就看代码吧。没啥好说的了。
class Trie {
public:
/** Initialize your data structure here. */
Trie() {
root = new TrieNode();
}
/** Inserts a word into the trie. */
void insert(string word) {
if (word.empty()) {return;}
const int n = word.size();
TrieNode* node = root;
int index = ;
for (int i = ; i < n; ++i) {
index = word[i] - 'a';
if (node->mp.find(index) == node->mp.end()) {
node->mp[index] = new TrieNode();
}
node = node->mp[index];
node->path++;
}
node->end++;
}
/** Returns if the word is in the trie. */
bool search(string word) {
if (word.empty()) {return false;}
TrieNode* node = root;
const int n = word.size();
int index = ;
for (int i = ; i < n; ++i) {
index = word[i] - 'a';
if (node->mp.find(index) == node->mp.end()) {
return false;
}
node = node->mp[index];
if (node->path == ) {
return false;
}
}
return node->end >= ;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
if (prefix.empty()) {return false;}
const int n = prefix.size();
TrieNode* node = root;
int index = ;
for (int i = ; i < n; ++i) {
index = prefix[i] - 'a';
if (node->mp.find(index) == node->mp.end()) {
return false;
}
node = node->mp[index];
if (node->path == ) {
return false;
}
}
return node->path >= ;
}
//define trie node
struct TrieNode{
int path; //代表多少个单词共用这个结点
int end; //代表多少个单词以这个结点结尾
map<int, TrieNode*> mp;
TrieNode() {
path = , end = ;
}
};
TrieNode* root;
};
/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* bool param_2 = obj.search(word);
* bool param_3 = obj.startsWith(prefix);
*/
【211】Add and Search Word - Data structure design (2018年11月27日)
实现这两个接口:(1) void addWord(word); (2) bool search(word)。 search 的时候输入有可能是个正则表达式。'.' 字符代表任何一个字母。输入保证只有小写字母和'. 。
题解:本题比 208 题更加多了一些条件,如果 search 的时候发现 word[i]是 '.' 的时候, 用 backtracking 递归做。
class WordDictionary {
public:
struct TrieNode {
int path;
int end;
map<int, TrieNode*> mp;
TrieNode() {
path = ;
end = ;
}
};
/** Initialize your data structure here. */
WordDictionary() {
root = new TrieNode();
}
/** Adds a word into the data structure. */
void addWord(string word) {
if (word.empty()) {return;}
const int n = word.size();
TrieNode* node = root;
int index = ;
for (int i = ; i < n; ++i) {
index = word[i] - 'a';
if (node->mp.find(index) == node->mp.end()) {
node->mp[index] = new TrieNode();
}
node = node->mp[index];
node->path++;
}
node->end++;
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
bool search(string word) {
if (word.empty()) {return false;}
return search(word, , root);
}
bool search(string word, int cur, TrieNode* node) {
const int n = word.size();
if (cur == n) {
if (node->end >= ) {
return true;
}
return false;
}
if (word[cur] == '.') {
map<int, TrieNode*> mptemp = node->mp;
TrieNode* father = node;
for (auto ele : mptemp) {
node = ele.second;
if (search(word, cur+, node)) {
return true;
}
node = father;
}
return false;
} else {
int index = word[cur] - 'a';
if (node->mp.find(index) == node->mp.end()) {
return false;
}
node = node->mp[index];
if (node->path == ) {
return false;
}
return search(word, cur+, node);
}
return true;
}
TrieNode* root;
};
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* bool param_2 = obj.search(word);
*/
【212】Word Search II
【336】Palindrome Pairs
【421】Maximum XOR of Two Numbers in an Array
【425】Word Squares
【472】Concatenated Words
【642】Design Search Autocomplete System
【648】Replace Words
【676】Implement Magic Dictionary
【677】Map Sum Pairs (2019年3月26日)
实现两个method,
Implement a MapSum class with insert, and sum methods.
For the method insert, you'll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.
For the method sum, you'll be given a string representing the prefix, and you need to return the sum of all the pairs' value whose key starts with the prefix.
Example 1:
Input: insert("apple", 3), Output: Null
Input: sum("ap"), Output: 3
Input: insert("app", 2), Output: Null
Input: sum("ap"), Output: 5
题解:用trie树,用map记录当前key是否在trie树里面,如果在的话,需要覆盖当前的值。
class TrieNode {
public:
TrieNode(char _c) : c(_c), pass() {
children.resize(, nullptr);
}
char c;
vector<TrieNode*> children;
int pass = ;
};
class MapSum {
public:
/** Initialize your data structure here. */
MapSum() {
root = new TrieNode('/');
}
~MapSum() {
if (root) delete root;
}
void insert(string key, int val) {
if (cache.count(key)) {
int diff = val - cache[key];
cache[key] = val;
val = diff;
} else {
cache[key] = val;
}
TrieNode* node = root;
for (auto& c : key) {
if (node->children[c-'a'] == nullptr) {
node->children[c-'a'] = new TrieNode(c);
}
node = node->children[c-'a'];
node->pass += val;
}
}
int sum(string prefix) {
if (!root) {return ;}
TrieNode* node = root;
for (auto& c : prefix) {
if (node->children[c-'a'] == nullptr) {return ;}
node = node->children[c-'a'];
}
return node->pass;
}
TrieNode* root;
unordered_map<string, int> cache;
};
/**
* Your MapSum object will be instantiated and called as such:
* MapSum* obj = new MapSum();
* obj->insert(key,val);
* int param_2 = obj->sum(prefix);
*/
【692】Top K Frequent Words
【720】Longest Word in Dictionary (2019年2月14日,谷歌tag)
给了一个 wordlist, 返回一个最长的单词,这个单词必须是每次从尾部扔掉一个字母的单词,依然在wordlist中。
题解:我用了trie树 + sorting,先用wordlist中所有的单词insert进 trie 树,然后排序后从最长的单词开始,检查是否符合规则 ,time complexity: O(sigma(Wi) + nlogn)
class Trie {
public:
class TrieNode {
public:
TrieNode(char ch) :c(ch) {
children.resize(, nullptr);
}
~TrieNode() {
for (auto node : children) {
delete node;
}
}
char c;
vector<TrieNode*> children;
bool isEnd = false;
};
Trie(): root(new TrieNode('/')) {}
std::unique_ptr<TrieNode> root; // TrieNode* root;
void insert(string& s) {
TrieNode* cur = root.get();
for (auto& letter : s) {
if (cur->children[letter-'a'] == nullptr) {
cur->children[letter-'a'] = new TrieNode(letter);
}
cur = cur->children[letter - 'a'];
}
cur->isEnd = true;
}
bool check(string& s) {
TrieNode* cur = root.get();
for (auto& letter : s) {
cur = cur->children[letter-'a'];
if (!cur->isEnd) {return false;}
}
return true;
}
};
class Solution {
public:
string longestWord(vector<string>& words) {
Trie trie;
//sort(words.begin(), words.end(), cmp);
sort(words.begin(), words.end(),
[](const string& s1, const string& s2) {
if (s1.size() != s2.size()) {
return s1.size () > s2.size();
}
return s1 < s2;
});
for (auto& w : words) {
trie.insert(w);
}
string res = "";
for (auto& w : words) {
if (trie.check(w)) {
return w;
}
}
return "";
}
static bool cmp(const string& s1, const string& s2) {
if (s1.size() == s2.size()) {
return s1 < s2;
}
return s1.size() > s2.size();
}
};
【745】Prefix and Suffix Search
【LeetCode】前缀树 trie(共14题)的更多相关文章
- 【LeetCode】树(共94题)
[94]Binary Tree Inorder Traversal [95]Unique Binary Search Trees II (2018年11月14日,算法群) 给了一个 n,返回结点是 1 ...
- 【暑假】[实用数据结构]前缀树 Trie
前缀树Trie Trie可理解为一个能够快速插入与查询的集合,无论是插入还是查询所需时间都为O(m) 模板如下: +; ; struct Trie{ int ch[maxnode][sigma_siz ...
- UVa 11732 "strcmp()" Anyone? (左儿子右兄弟前缀树Trie)
题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php? ...
- 【SpringBoot】前缀树 Trie 过滤敏感词
1.过滤敏感词 Spring Boot实践,开发社区核心功能 完成过滤敏感词 Trie 名称:Trie也叫做字典树.前缀树(Prefix Tree).单词查找树 特点:查找效率高,消耗内存大 应用:字 ...
- 【LeetCode】二叉查找树 binary search tree(共14题)
链接:https://leetcode.com/tag/binary-search-tree/ [220]Contains Duplicate III (2019年4月20日) (好题) Given ...
- 【LeetCode】数学(共106题)
[2]Add Two Numbers (2018年12月23日,review) 链表的高精度加法. 题解:链表专题:https://www.cnblogs.com/zhangwanying/p/979 ...
- 【LeetCode】BFS(共43题)
[101]Symmetric Tree 判断一棵树是不是对称. 题解:直接递归判断了,感觉和bfs没有什么强联系,当然如果你一定要用queue改写的话,勉强也能算bfs. // 这个题目的重点是 比较 ...
- 【LeetCode】Recursion(共11题)
链接:https://leetcode.com/tag/recursion/ 247 Strobogrammatic Number II (2019年2月22日,谷歌tag) 给了一个 n,给出长度为 ...
- Trie(前缀树/字典树)及其应用
Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...
随机推荐
- tomcat安全配置参考
0x01 基本配置 1 删除默认目录 安装完tomcat后,删除$CATALINA_HOME/webapps下默认的所有目录文件 rm -rf /srv/apache-tomcat/webapps/ ...
- [CSP-S模拟测试]:e(树上主席树)
题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...
- mysqldump常用使用
1:导出数据库sakila的表结构mysqldump -uroot -ppwd -d sakila > /data/tmp/sakila.sql; 2:导出数据库sakila下表employee ...
- 【洛谷P1383 高级打字机】
题目描述 早苗入手了最新的高级打字机.最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧. 请为这种高级打字机设计一个程序,支持如下3种操作: 1.T x:在文章末尾打下一个小写字母x.(t ...
- CyclicBarrier 源码分析
CyclicBarrier CyclicBarrier 是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point) 之后同时释放执行.CyclicB ...
- 如何利用EDM邮件营销进行持续推销
一般来说,一个电子商务网站的转化率在2%左右是正常的.这也意味着其他98%的潜在客户并不会购买任何东西,并且可能再也不回来了.这个时候,如何利用EDM邮件营销进行持续推销呢? 首先,EDM邮件营销可以 ...
- Linux_LDAP+NFS+autofs
目录 目录 前言 Ldap LDAPNFSautofs ServerPost 前言 LDAP+NFS+Autofs也是一种网络用户集中管理解决方案,相对于NIS+NFS+Autofs而言,有着更可靠的 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_9_JDK7和JDK9流中异常的处理
jdk7 jdk9
- android dialog,popupwindow,toast窗口的添加机制
Dialog 窗口添加机制 代码示例 首先举两个例子: 例子1 在Activity中 @OnClick(R.id.but) void onClick() { Log.d("LiaBin&qu ...
- 【MM系列】SAP MM中的委外加工与信息记录
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM中的委外加工与信息记录 ...