题目

示例

思路

前缀:字符串的前缀是指字符串的任意首部。比如字符串“abbc”的前缀有“a”,“ab”,“abb”,“abbc”。
前缀树:前缀树是一种用于快速检索的多叉树结构,利用字符串的公共前缀来降低查询时间,核心思想是空间换时间,经常被搜索引擎用于文本词频统计。前缀树多用于字符串。
思路
将本题dictionary转换为前缀树,然后对sentence遍历,判断字符串前缀是否位于树上,存在就进行简化输出,不存在就完全输出,最后定义的字符串链接所有结果的比较结果
以下代码还可以优化

代码

//0:结束,1:没有结束
typedef struct word{int end;struct word * next[26];
}word;/* 1:表示未结束  0:表示结束*/
word * trieCreate(){word * obj = malloc(sizeof(word) * 1);for(int i = 0; i < 26; i++){obj->next[i] = NULL;}obj->end = 0;;return obj;
}
/*
*void trieInsert(Trie* obj, char * word)
void trieInsert:向前缀数插入字符串
Trie* obj:前缀树头结点
char * word:字符串
返回值:无
*/
void word_create(word * root, char ** dictionary, int inode)
{int len = strlen(dictionary[inode]);for(int i = 0; i < len; i++){if(root->next[dictionary[inode][i] - 'a'] == NULL){word * n = trieCreate();root->next[dictionary[inode][i] - 'a'] = n;}root = root->next[dictionary[inode][i] - 'a'];}root->end = 1;
}
/*
*char * str_if(word * root, char * sentence, int len_left, int len_right)
char * str_if:判断字符串前缀是否在前缀树上
word * root:前缀树头结点
char * sentence:比较字符串
int len_left:比较字符串的左节点
int len_right:比较字符串的右节点
返回值:存在就输出存在部分,不存在就不简化输出
*/
char * str_if(word * root, char * sentence, int len_left, int len_right)
{int len = 0;for(int i = len_left; i < len_right; i++){if(root->next[sentence[i] - 'a'] && root->end == 0){len++;root = root->next[sentence[i] - 'a'];}else{if(root->end == 0){len = len_right - len_left;}break;}}if(len)//简化{char * str = malloc(sizeof(char) * (len + 1 + 1));strncpy(str, sentence+len_left, len);str[len] = ' ';str[len + 1] = '\0';return str;}else//不简化,代码还可以优化{char * str = malloc(sizeof(char) * (len_right - len_left + 1 + 1));strncpy(str, sentence+len_left, len_right - len_left);str[len_right - len_left] = ' ';str[len_right - len_left + 1] = '\0';return str;}return NULL;
}
/*
*char * replaceWords(char ** dictionary, int dictionarySize, char * sentence)
char * replaceWords:将字符串根据字典进行优化
char ** dictionary:字典
int dictionarySize:字典行数
char * sentence:字符串
返回值:优化后的字符串
*/
char * replaceWords(char ** dictionary, int dictionarySize, char * sentence){char * str = malloc(sizeof(char) * (1000 * 1000 + 1));str[0] = '\0';word * root = trieCreate();for(int i = 0; i < dictionarySize; i++){   word_create(root, dictionary, i);}int len = strlen(sentence);int len_left = 0;int i;for(i = 0; i < len; i++){if(sentence[i] == ' '){strcat(str , str_if(root, sentence, len_left, i));len_left = i+1;}}strcat(str , str_if(root, sentence, len_left, i));len = strlen(str);str[len - 1] = '\0';trieFree(root);return str;
}
//销毁前缀树
void trieFree(word * obj) {for(int i = 0; i < 26; i++){if(obj->next[i])trieFree(obj->next[i]);}free(obj);
}

时间空间复杂度

每日一题·648.单词替换·前缀树相关推荐

  1. 648. 单词替换 : 字典树的经典运用

    题目描述 这是 LeetCode 上的 648. 单词替换 ,难度为 中等. Tag : 「字典树」 在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词 ...

  2. leetcode每日一题--前缀树;前缀哈希;深搜;面试题 08.04. 幂集;648. 单词替换面试题 01.09. 字符串轮转;剑指 Offer II 062. 实现前缀树

    leetcode每日一题 ps:今天的每日一题没意思,简单的模拟,自己换一道 面试题 08.04. 幂集 幂集.编写一种方法,返回某集合的所有子集.集合中不包含重复的元素. 说明:解集不能包含重复的子 ...

  3. 字典树/Trie/前缀树-LeetCode总结:720词典中最长的单词;127. 单词接龙;677. 键值映射;面试题 17.17. 多次搜索;648. 单词替换

    MyTrie结构体和相关操作函数 typedef struct MyTrie {bool is_word;vector<MyTrie*> next;MyTrie():is_word(fal ...

  4. LeetCode 648. 单词替换

    文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述   在英语中,我们有一个叫 ...

  5. Leetcode 648.单词替换(Replace Words)

    Leetcode 648.单词替换 1 题目描述(Leetcode题目链接)   在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词( ...

  6. 【C语言蓝桥杯每日一题】—— 单词分析

    [C语言蓝桥杯每日一题]-- 单词分析

  7. LeetCode 648. 单词替换(Trie树)

    1. 题目 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other(其他), ...

  8. 【LeetCode】720. 词典中最长的单词 【前缀树】

    题目链接:https://leetcode-cn.com/problems/longest-word-in-dictionary/ 题目描述 给出一个字符串数组words组成的一本英语词典.从中找出最 ...

  9. Leetcode 648.单词替换

    单词替换 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other(其他),可 ...

最新文章

  1. Python 笔试集(2):你不知道的 Python 整数
  2. 二叉树深度优先遍历和广度优先遍历
  3. mysql和sql互导_Mysql和SqlServer互相转换
  4. leaflet的入门开发(一)
  5. JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet
  6. OpenCV中Mat的属性
  7. 【渝粤教育】电大中专财务管理与分析 (2)作业 题库
  8. 前端学习(2818):小程序学习之新建页面
  9. LeetCode 727. 最小窗口子序列(滑动窗口)
  10. 什么样的程序员是最让人讨厌的?朋友们注意了,别做这种人!
  11. [开源]430驱动的12864图形点阵LCD
  12. 微服务架构工作笔记003---了解认识google Kubernetes 容器管理
  13. 我的Android学习之路
  14. 李彦宏谈无人车:高速上吃着火锅唱着歌,再有三五年能代替司机
  15. 每日算法系列【LeetCode 556】下一个更大元素 III
  16. Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)
  17. JavaScript数组forEach方法
  18. 酒店短视频营销,是酒店获客引流的重点推广手段之一
  19. 网络安全架构与域划分(企业安全)
  20. java if中的continue_java中break和continue源码解析

热门文章

  1. DB DBMS SQL 分别是什么?
  2. 网络信息传播中图像识别技术的意义
  3. matlab解决推销员行程问题(可参考mathworks网站)
  4. 《C语言程序设计》江宝钏主编-习题8-4-复制字串!!!
  5. nginx-----部署集群
  6. USB设备的VID与PID
  7. 性能测试工具操作数据库(十)-Loadrunner与Redis
  8. JWPlayer Flash播放器如何实现视频分段载入播放从而节省带宽?
  9. 实战分析!三面蚂蚁核心金融部,稳进大厂
  10. 使用 Excel 画像素画