【字典树】添加和查找单词
为什么80%的码农都做不了架构师?>>>
Add and Search Word - Data structure design
问题:
Design a data structure that supports the following two operations:
void addWord(word) bool search(word)
search(word) can search a literal word or a regular expression string containing only letters a-z
or .
. A .
means it can represent any one letter.
For example:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
Note:
You may assume that all words are consist of lowercase letters a-z
.
hint:
You should be familiar with how a Trie works. If not, please work on this problem: Implement Trie (Prefix Tree) first.
解决:
① 要求实现添加和查找单词,实际上是实现向字典树种添加词组,并可以查找匹配词组。与 Implement Trie (Prefix Tree) 相似,这道题里面'.'可以代替任意字符,所以一旦有了'.',就需要查找所有的子树,只要有一个返回true,整个search函数就返回true。
class TrieNode{//222ms
char c;//当前节点的字符
Map<Character,TrieNode> children = new HashMap<>();//当前节点的子节点,以当前节点的字符作为key
boolean isLeaf;
public TrieNode(){}
public TrieNode(char c){
this.c = c;
}
}
public class WordDictionary{
private TrieNode root;//指定根节点,没有字符。
public WordDictionary(){
root = new TrieNode();//根节点没有字符
}
public void addWord(String word){
Map<Character,TrieNode> cur = root.children;//从根节点的子节点开始向下添加
for (int i = 0;i < word.length() ;i ++ ) {
char c = word.charAt(i);//当前要插入的字符
TrieNode tmp = null;//对应的节点
if (cur.containsKey(c)) {//当前字符对应的节点已经存在了
tmp = cur.get(c);//获取遍历到的节点
}else{
tmp = new TrieNode(c);
cur.put(c,tmp);
}
cur = tmp.children;
if (i == word.length() - 1) {
tmp.isLeaf = true;
}
}
}
public boolean search(String word){
return dfsSearch(root.children,word,0);
}
public boolean dfsSearch(Map<Character,TrieNode> cur,String word,int i){
if (i == word.length()) {
if (cur.size() == 0) {//节点与单词都遍历完了
return true;
}else{
return false;
}
}
char c = word.charAt(i);
if (cur.containsKey(c)) {
if (i == word.length() - 1 && cur.get(c).isLeaf) {
return true;
}
return dfsSearch(cur.get(c).children,word,i + 1);
}else if(c == '.'){
boolean res = false;
for (Map.Entry<Character,TrieNode> child : cur.entrySet()) {
if (i == word.length() - 1 && child.getValue().isLeaf) {
return true;
}
if(dfsSearch(child.getValue().children,word,i + 1)){
res = true;
}
}
return res;
}else{
return false;
}
}
}
② 使用数组代替Map。
class TrieNode{//186ms
TrieNode[] children;
boolean isLeaf;
public TrieNode(){//单词中全部为26个小写字母。
children = new TrieNode[26];
}
}
public class WordDictionary {
TrieNode root;
public WordDictionary(){
root = new TrieNode();//根节点为空
}
public void addWord(String word){
TrieNode cur = root;
for (int i = 0;i < word.length() ;i ++ ) {//构造前缀树
char c = word.charAt(i);
int index = c - 'a';//在孩子节点中的位置
if (cur.children[index] == null) {
TrieNode tmp = new TrieNode();
cur.children[index] = tmp;
cur = tmp;
}else{
cur = cur.children[index];
}
}
cur.isLeaf = true;
}
public boolean search(String word){
return dfsSearch(root,word,0);
}
public boolean dfsSearch(TrieNode cur,String word,int i){
if (i == word.length() && cur.isLeaf) {
return true;
}
if (i >= word.length()) {
return false;
}
char c = word.charAt(i);
if (c == '.') {
boolean res = false;
for (int j = 0;j < 26 ;j ++ ) {//查看是否有匹配的子节点
if (cur.children[j] != null) {
if (dfsSearch(cur.children[j],word,i + 1)) {
res = true;
break;
}
}
}
if (res) {
return true;
}
}else{
int index = c - 'a';
if (cur.children[index] != null) {
return dfsSearch(cur.children[index],word,i + 1);
}else{
return false;
}
}
return false;
}
}
③ 在discuss中看到的,使用map保存节点及其对应路径上的长度,值为字符串的长度,键为对应的字符串的长度。
public class WordDictionary{//160ms
//使用map构造前缀树,使用链表保存节点值.键为字符串长度,值为对应的字符串
Map<Integer,List<String>> map = new HashMap<>();
public void addWord(String word){
int index = word.length();
if (! map.containsKey(index)) {
List<String> list = new ArrayList<>();
list.add(word);
map.put(index,list);
}else{
map.get(index).add(word);
}
}
public boolean search(String word){
int index = word.length();
if(! map.containsKey(index)){
return false;
}
List<String> list = map.get(index);
for (String s : list) {
if (isSame(s,word)) {
return true;
}
}
return false;
}
public boolean isSame(String root,String search){
if (root.length() != search.length()) {
return false;
}
for (int i = 0;i < root.length() ;i ++ ) {
if (search.charAt(i) != '.' && search.charAt(i) != root.charAt(i)) {
return false;
}
}
return true;
}
}
转载于:https://my.oschina.net/liyurong/blog/1575284
【字典树】添加和查找单词相关推荐
- Tire树(字典树-字符串快速查找)
前言 一.Tire树是什么? 二.怎么建立tire树 1.字符串插入Tire树入 2.查找字符串 总结 前言: 最近是在复习基础算法,正好复习到了数据结构,所以写了自己对Tire树的理解,数据结构对我 ...
- 字典树c语言,字典树的应用 单词意义查找-C语言实现
下面是编程之家 jb51.cc 通过网络收集整理的代码片段. 编程之家小编现在分享给大家,也给大家做个参考. 实现根据单词快速找到对应的解释 /* 字典树应用,快速单词查找 */ const int ...
- c语言 trie树,C语言实现Trie树(字典树)的插入查找删除与遍历操作
Trie树,也称作是字典树,是一种哈希树的变种,查询效率较高.Trie树可以用于统计或者排序大量的字符串,比如对一系列字符串按照字典序排序. 字典树是一个多叉树,每一个节点上存储的不是一个字符串,而是 ...
- 【前缀树】C++ 数据结构 字典树
之前有段时间力扣天天出字典树,当时写得特别熟练,几个月没做都忘得差不多了--今天又出了相关题目,正好复习一下. 文章目录 一.前缀树是什么? 二.实现前缀树 三.例题:添加与搜索单词 总结 一.前缀树 ...
- 字典树Trim详解+相关例题---龙之介算法基础课
字典树,顾名思义,是关于"字典"的一棵树. 即:它是对于字典的一种存储方式(所以是一种数据结构而不是算法). 这个词典中的每个"单词"就是从根节点出发一直到某一 ...
- Trie(字典树/前缀树)
字典树/前缀树 Trie(发音类似 "try")或者说 前缀树(字典树) 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键.这一数据结构有相当多的应用情景,例如自动补完和 ...
- #1117. 编码 ( 字典树版 ) 题解分析
[问题描述] 我们准备根据一份文本编码表对一篇文本进行压缩.编码表的每一项包含两个部分:要编码的字符串和对应的编码.编码是二进制的01串,用来替代文本中相应的字符串以实现压缩编码的目的.这些01串不一 ...
- 字典树 ZOJ1109 HDU1251 PKU1204 HDU1075
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:利用字符串的公共前缀 ...
- Kiner算法刷题记(二十一):字典树与双数组字典树(数据结构基础篇)
字典树与双数组字典树(数据结构基础篇) 系列文章导引 系列文章导引 开源项目 本系列所有文章都将会收录到GitHub中统一收藏与管理,欢迎ISSUE和Star. GitHub传送门:Kiner算法算题 ...
最新文章
- 阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...
- 图论 ---- dijkstra变种dp Codeforces Div2 703 E. Paired Payment
- autofs一个神奇的服务
- 遍历Collection,避免在循环中删除对象时避免ConcurrentModificationException
- Appium 命令行安装教程
- 关于初学Go的一些总结
- PRISM概率模型检测器初使用--骰子模型(改进版)
- IBATISNETNET 1.3 开发指南系列文章
- PAT (Advanced Level) 1003 Emergency(最短路+动态规划)
- 今天会议的召开,和你有关系吗?
- linux中内存挂载到目录下
- VMware View虚拟桌面在安卓平板电脑上的演示
- Spring Boot 2.x 集成 Quartz 定时器 jdbc 持久化、配置集群
- 谷歌地球看不了街景_PPT放入3D模型之后,居然能模拟谷歌地图!
- iOS 常用正则表达式一览表
- 中国人为何无缘诺贝尔奖
- 开源python语音识别_5 款不错的开源语音识别/语音文字转换系统
- android 自定义 snackbar,Android Study Material Design 五 之:自定义Toast以及玩转SnackBar...
- Profibus-Dp 工作过程介绍
- “一起吧”低调上线,百度社交还有机会吗?