Trie 树的模板

Trie 树的简介

Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。他的核心思想是空间换时间,空间消耗大但是插入和查询有着很优秀的时间复杂度。

Trie 树的定义

Trie树的键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀(prefix),从根节点到当前结点的路径上的所有字母组成当前位置的字符串,结点可以保存当前字符串、出现次数、指针数组(指向子树)以及是否是结尾标志等等。

简图

实际上每个节点有一个end属性和一个字典长度的节点数组

Trie 树的实现

LeetCode 208. 实现 Trie (前缀树)

Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

请你实现 Trie 类:

Trie() 初始化前缀树对象。
void insert(String word) 向前缀树中插入字符串 word 。
boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。
boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。
  示例: 输入
["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
输出
[null, null, true, false, true, null, true] 解释
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 True
trie.search("app"); // 返回 False
trie.startsWith("app"); // 返回 True
trie.insert("app");
trie.search("app"); // 返回 True
  提示: 1 <= word.length, prefix.length <= 2000
word 和 prefix 仅由小写英文字母组成
insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次
class Trie {
class TrieNode {
boolean end;
TrieNode[] tns = new TrieNode[26];
}
TrieNode root;
public Trie() {
root = new TrieNode();
} public void insert(String word) {
TrieNode p = root;
for(int i = 0; i < word.length(); i++) {
int u = word.charAt(i) - 'a';
if(p.tns[u] == null) p.tns[u] = new TrieNode();
p = p.tns[u];
}
p.end = true;
} public boolean search(String word) {
TrieNode p = root;
for(int i = 0; i < word.length(); i++) {
int u = word.charAt(i) - 'a';
if(p.tns[u] == null) return false;
p = p.tns[u];
}
return p.end;
} public boolean startsWith(String prefix) {
TrieNode p = root;
for(int i = 0; i < prefix.length(); i++) {
int u = prefix.charAt(i) - 'a';
if(p.tns[u] == null) return false;
p = p.tns[u];
}
return true;
}
}

Trie 树的例题

LeetCode 211. 添加与搜索单词

LeetCode 211. 添加与搜索单词

请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary :

WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回  false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
  示例: 输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true] 解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True
  提示: 1 <= word.length <= 500
addWord 中的 word 由小写英文字母组成
search 中的 word 由 '.' 或小写英文字母组成
最多调用 50000 次 addWord 和 search
class WordDictionary {
class Node {
boolean end;
Node[] tns = new Node[26];
}
Node root;
public void insert(String s) {
Node p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if(p.tns[u] == null) p.tns[u] = new Node();
p = p.tns[u];
}
p.end = true;
}
public WordDictionary() {
root = new Node();
} public void addWord(String word) {
insert(word);
} public boolean search(String s) {
return dfs(s, root, 0);
}
public boolean dfs(String s, Node p, int idx) {
int n = s.length();
if(idx == n) return p.end;
char c = s.charAt(idx);
if(c == '.') {
for(int i = 0; i < 26; i++) {
if(p.tns[i] != null && dfs(s, p.tns[i], idx + 1)) return true;
}
return false;
}
else {
int u = c - 'a';
if(p.tns[u] == null) return false;
return dfs(s, p.tns[u], idx + 1);
}
}
}

LeetCode 720. 词典中最长的单词

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

 

示例 1:

输入:words = ["w","wo","wor","worl", "world"]
输出:"world"
解释: 单词"world"可由"w", "wo", "wor", 和 "worl"逐步添加一个字母组成。
示例 2: 输入:words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
输出:"apple"
解释:"apply" 和 "apple" 都能由词典中的单词组成。但是 "apple" 的字典序小于 "apply"
  提示: 1 <= words.length <= 1000
1 <= words[i].length <= 30
所有输入的字符串 words[i] 都只包含小写字母。
class Solution {
class Trie {
class TrieNode {
boolean end;
TrieNode[] tns = new TrieNode[26];
}
TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if(p.tns[u] == null) {
p.tns[u] = new TrieNode();
}
p = p.tns[u];
}
p.end = true;
}
public boolean search(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if(p.tns[u] == null) return false;
p = p.tns[u];
}
return p.end;
}
public boolean startsWith(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if(p.tns[u] == null) return false;
p = p.tns[u];
}
return true;
}
public boolean query(String s) {
TrieNode p = root;
for(int i = 0; i < s.length(); i++) {
int u = s.charAt(i) - 'a';
if(p.tns[u] == null) return false;
if(p.tns[u].end == false) return false;
p = p.tns[u];
}
return true;
}
}
public String longestWord(String[] words) {
Trie t = new Trie();
for(String word : words) {
t.insert(word);
}
String ans = "";
for(String word : words) {
int lena = ans.length();
int lenb = word.length();
if(lenb < lena) continue;
if(lenb == lena && word.compareTo(ans) > 0) continue;
if(t.query(word)) ans = word;
}
return ans;
}
}

【数据结构与算法】Trie(前缀树)模板和例题的更多相关文章

  1. 第15个算法-实现 Trie (前缀树)(LeetCode)

    解法代码来源 :https://blog.csdn.net/whdAlive/article/details/81084793 算法来源:力扣(LeetCode)链接:https://leetcode ...

  2. 数据结构—— Trie (前缀树)

    实现一个 Trie (前缀树),包含 插入, 查询, 和 查询前缀这三个操作. Trie trie = new Trie(); trie.insert("apple"); trie ...

  3. python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie)

    python利用Trie(前缀树)实现搜索引擎中关键字输入提示(学习Hash Trie和Double-array Trie) 主要包括两部分内容:(1)利用python中的dict实现Trie:(2) ...

  4. leetcode 208. 实现 Trie (前缀树)

    实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert(" ...

  5. 力扣208——实现 Trie (前缀树)

    这道题主要是构造前缀树节点的数据结构,帮助解答问题. 原题 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = ...

  6. [Swift]LeetCode208. 实现 Trie (前缀树) | Implement Trie (Prefix Tree)

    Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...

  7. 实现 Trie (前缀树)

    实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie(); trie.insert(" ...

  8. Java实现 LeetCode 208 实现 Trie (前缀树)

    208. 实现 Trie (前缀树) 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie() ...

  9. 力扣 - 208. 实现Trie(前缀树)

    目录 题目 思路 代码 复杂度分析 题目 208. 实现 Trie (前缀树) 思路 在我们生活中很多地方都用到了前缀树:自动补全,模糊匹配,九宫格打字预测等等... 虽然说用哈希表也可以实现:是否出 ...

  10. [leetcode] 208. 实现 Trie (前缀树)(Java)

    208. 实现 Trie (前缀树) 实现Trie树,网上教程一大堆,没啥可说的 public class Trie { private class Node { private int dumpli ...

随机推荐

  1. Ubuntu下Java JDK安装

    1.仓库安装 待更新 2.手动安装 1.下载linux平台sdk. 官网:https://www.oracle.com/technetwork/java/javase/downloads/index. ...

  2. Maven多环境配置实战 filter

    目前在开发一个wap项目,主要有开发.测试和最终部署上线几个阶段,每个阶段对配置(数据库.日志)都有不同的设置.以前都是以开发环境为主,在测试和部署上线时由部署工程师负责修改配置并上线.但是公司并非都 ...

  3. 使用Docker安装ElasticSearch和可视化界面Kibana【图文教学】

    一.前言 Elasticsearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java语言开发的,并 ...

  4. Linux基础:子网划分

    一.ip地址基本知识 1.1 ip地址的结构和分类 1.2 特殊ip地址 1.3 子网掩码 1.4 ip地址申请 二.子网划分 2.1 子网划分概念 2.2 c类子网划分初探 2.3 子网划分步骤 2 ...

  5. 使用Supervisord部署go应用

    nohup nohup 是后台作业的意思, nohup运行的进程将会忽略终端信号运行.即后台运行一个命令.nohup COMMAND &用nohup运行命令可以使命令永久的执行下去,和用户终端 ...

  6. Swagger2简单实用

    前后端分离很好用的api <!--swagger--> <dependency> <groupId>io.springfox</groupId> < ...

  7. 【Kotlin】初识Kotlin之面向对象

    [Kotlin]初识Kotlin之面向对象 1.类 在Kotlin中,类用关键字class来定义 如果一个类具有类体,那么需要使用{ }来写类体内容,如果不需要类体,那么只需要定义类名就可以了 // ...

  8. bugku 神秘的文件

      题目链接: https://ctf.bugku.com/challenges#%E7%A5%9E%E7%A7%98%E7%9A%84%E6%96%87%E4%BB%B6 工具准备: 1.PC 2. ...

  9. 网络测试技术——802.1X原理

    一.以太网优点缺点 1.以太网优点 (1)即插即用,简单快捷 (2)任何一台电脑只要接入网络便有访问网络资源的权限 2.以太网缺点 (1)缺乏安全认证机制(二层) (2)电脑接到交换机上就能访问网络 ...

  10. Oracle之SQL语句的分类

    SQL简介 SQL:结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库 ...