链接:https://leetcode.cn/problems/implement-magic-dictionary/solution/by-xun-ge-v-3c60/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

题目

示例

思路

本题为前缀树和dfs的一个结合
求解字符串s(searchWord)在另外一个字典集d(dictionary)中相关操作都可以运用
前缀树https://leetcode.cn/problems/implement-trie-prefix-tree/solution/chun-c-by-xun-ge-v-vnt5/
进行优化,力扣也有关于前缀树实现的习题,对前缀树不了解的可以进链接

前缀树:前缀树是一种用于快速检索的多叉树结构,利用字符串的公共前缀来降低查询时间,核心思想是空间换时间,经常被搜索引擎用于文本词频统计。
    typedef struct MagicDictionary{
        bool logo;//true表示字符串结束,false表示字符未结束
        struct MagicDictionary * next[26];
    } MagicDictionary; 
其中前缀树中每一个节点代表一个字符,以一个节点进行深度优先搜索,一直到末尾,那么经过的路径就为字典集中的一个字符串
具体实现
先对字典集d进行优化,转换为对应的前缀树,将所有的d子串存入字典树中,方便后续检索;
设计递归函数dfs(MagicDictionary * obj, char * searchWord, int inode, int len, int x),searchWord其中为待检索的字符串,inode为当前处理到字符串 s 的哪一位,obj为当前搜索到字典树的索引编号,x为当前剩余的替换字符次数,根据题意,x固定为 1,含义为必须替换掉 s 的一个字符。
对于s而言,我们可以枚举新字符串在当前位置是何种字符(i = 26个选择),若当前枚举到的字符与 s[inode] 一致,则不消耗替换次数。
递归过程中替换次数为负数直接剪枝,当递归到字符串s结尾位置,检查是否位于前缀树末尾,并且x为0

代码

//前缀树 + 递归 + 深度优先搜索
typedef struct MagicDictionary{bool logo;//true表示字符串结束,false表示字符未结束struct MagicDictionary * next[26];
} MagicDictionary; //初始化
MagicDictionary* magicDictionaryCreate() {MagicDictionary * obj = malloc(sizeof(MagicDictionary));for(int i = 0; i < 26; i++){obj->next[i] = NULL;}obj->logo = false;return obj;
}
//转换前缀树
void magicDictionaryBuildDict(MagicDictionary* obj, char ** dictionary, int dictionarySize) {if(dictionarySize > 1){magicDictionaryBuildDict(obj, dictionary, dictionarySize - 1);}int len = strlen(dictionary[dictionarySize-1]);for(int i = 0; i < len; i++){if(obj->next[dictionary[dictionarySize-1][i] - 'a'] == NULL){MagicDictionary * n = magicDictionaryCreate();obj->next[dictionary[dictionarySize-1][i] - 'a'] = n;}obj = obj->next[dictionary[dictionarySize-1][i] - 'a'];}obj->logo = true;
}
//递归判断字符串在字典树的情况
bool dfs(MagicDictionary * obj, char * searchWord, int inode, int len, int x)
{if(x < 0)//剪枝{return false;}if(inode == len)//到字符串末尾了,判断一下是否换了一个字符,是不是在字典集中存在完整的字符串{if(x == 0 && obj->logo == true){return true;}else{return false;}}for(int i = 0; i < 26; i++)//寻找同层前缀树中存在的元素{if(obj->next[i])//存在{if(i == (searchWord[inode] - 'a'))//是不是和目标元素一样{if(dfs(obj->next[i], searchWord, inode+1, len, x) == true){return true;}}   else//不一样,修改次数-1,继续{if(dfs(obj->next[i], searchWord, inode+1, len, x-1) == true){return true;}}}}return false;//前缀树遍历完了,没有字符串和s字符串匹配
}//调用dfs函数深度优先搜索
bool magicDictionarySearch(MagicDictionary* obj, char * searchWord) {int len = strlen(searchWord);return dfs(obj, searchWord, 0, len, 1);
}
//销毁前缀树
void magicDictionaryFree(MagicDictionary* obj) {for(int i = 0; i < 26; i++){if(obj->next[i]){magicDictionaryFree(obj->next[i]); }}free(obj);
}/*** Your MagicDictionary struct will be instantiated and called as such:* MagicDictionary* obj = magicDictionaryCreate();* magicDictionaryBuildDict(obj, dictionary, dictionarySize);* bool param_2 = magicDictionarySearch(obj, searchWord);* magicDictionaryFree(obj);
*/

时间空间复杂度

676.实现一个魔法字典·前缀树相关推荐

  1. LeetCode 676. 实现一个魔法字典

    文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述   设计一个使用单词列表进 ...

  2. 676. 实现一个魔法字典

    676. 实现一个魔法字典 设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 . 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的 ...

  3. leetcode 676. Implement Magic Dictionary | 676. 实现一个魔法字典(DFS+Trie 前缀树)

    题目 https://leetcode.com/problems/implement-magic-dictionary/description/ 题解 题意理解 前缀树问题,大意是是让你在字典中找到是 ...

  4. LeetCode 676. 实现一个魔法字典(哈希)

    1. 题目 实现一个带有buildDict, 以及 search方法的魔法字典. 对于buildDict方法,你将被给定一串不重复的单词来构建一个字典. 对于search方法,你将被给定一个单词,并且 ...

  5. trie(字典树、前缀树)

    trie(字典树.前缀树) 1. trie原理 原理 trie树,又被称为字典树.前缀树,是一种高效地存储和查找字符串集合的数据结构. 一般来说,用到trie的题目中的字母要么全是小写字母,要么全是大 ...

  6. 树结构-------前缀树

    何为前缀树:又叫字典树.单词查找树或键树,是一种多叉树结构.如下图 上图是一棵Trie树,表示了关键字集合{"a", "to", "tea" ...

  7. 前缀树(Trie)原理及Java实现

    前缀树的结构 Trie树,又叫字典树.前缀树(Prefix Tree).单词查找树或键树,是一种多叉树结构.如下图: 上图是一棵Trie树,表示了关键字集合{"a", " ...

  8. Trie(前缀树/字典树)及其应用

    from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...

  9. 字典数(前缀树)的实现

    [题目] 字典树又称为前缀树或者Trie树,是处理字符串常用的数据结构.假设组成所有单词的字符仅是'a'-'z',请实现字典树的结构,并包含以下四个主要的功能. void insert(String ...

最新文章

  1. 提升玩家游戏体验与账户安全,是游戏行业网络方案是重中之重
  2. java 线程一直运行状态_详解JAVA 线程-线程的状态有哪些?它是如何工作的?
  3. 多线程程序中操作的原子性
  4. linux shell 脚本实现:根据文件内容中的每行分隔符放入数组,根据规则打印日志并重新创建目录 备份文件
  5. C#字典转换成where条件
  6. 一幅图告诉你C-C++注释转换有多简单
  7. linux命令大全密码修改,linux修改密码命令
  8. mac 壁纸 android,Mac系统风格桌面
  9. 了解Linux操作系统
  10. 人脸识别技术全面总结
  11. rainyday.js 下雨效果插件使用方法
  12. 主干开发(Trunk-based development)
  13. 华为云主机安全防护的新发现
  14. 2020年最好用的手机是哪一款_2020年公认最值得入手的3款手机,颜值性能兼具,用三年不亏!...
  15. 软件测试面试-为什么选择软件测试?
  16. 二分查找算法(随机, 最左, 最右)
  17. 聊一聊回收科技那些事儿
  18. ImageMagick windows下的安装和gif动图制作
  19. 微信小程序Ⅴ [获取登录用户信息,重点openID(详解)]
  20. Mac电脑投屏到Linux,苹果电脑投屏到显示器的三种常见方式

热门文章

  1. SharePoint 2010 安装错误:请重新启动计算机,然后运行安装程序以继续
  2. c语言简单小游戏(模拟魔塔)
  3. Django个人博客搭建教程---用Vue写你的第一个前后端分离页面
  4. 【算法】哈夫曼压缩算法-学习记录
  5. 在Oracle中采用纵向和横向结构表
  6. lottie android 源码,Lottie动画库 Android 端源码浅析
  7. 戴戴戴师兄-数据分析课程笔记(第二讲)
  8. php mysql text换行符_请教php配合mysql的换行符和空格字符问题
  9. linux网口初始化_Linux 初始化系统配置(CentOS 6)
  10. 数据结构(C语言第2版) 课后习题答案之第五章 树和二叉树