每日一题·648.单词替换·前缀树
题目
示例
思路
前缀:字符串的前缀是指字符串的任意首部。比如字符串“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.单词替换·前缀树相关推荐
- 648. 单词替换 : 字典树的经典运用
题目描述 这是 LeetCode 上的 648. 单词替换 ,难度为 中等. Tag : 「字典树」 在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词 ...
- leetcode每日一题--前缀树;前缀哈希;深搜;面试题 08.04. 幂集;648. 单词替换面试题 01.09. 字符串轮转;剑指 Offer II 062. 实现前缀树
leetcode每日一题 ps:今天的每日一题没意思,简单的模拟,自己换一道 面试题 08.04. 幂集 幂集.编写一种方法,返回某集合的所有子集.集合中不包含重复的元素. 说明:解集不能包含重复的子 ...
- 字典树/Trie/前缀树-LeetCode总结:720词典中最长的单词;127. 单词接龙;677. 键值映射;面试题 17.17. 多次搜索;648. 单词替换
MyTrie结构体和相关操作函数 typedef struct MyTrie {bool is_word;vector<MyTrie*> next;MyTrie():is_word(fal ...
- LeetCode 648. 单词替换
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 在英语中,我们有一个叫 ...
- Leetcode 648.单词替换(Replace Words)
Leetcode 648.单词替换 1 题目描述(Leetcode题目链接) 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词( ...
- 【C语言蓝桥杯每日一题】—— 单词分析
[C语言蓝桥杯每日一题]-- 单词分析
- LeetCode 648. 单词替换(Trie树)
1. 题目 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other(其他), ...
- 【LeetCode】720. 词典中最长的单词 【前缀树】
题目链接:https://leetcode-cn.com/problems/longest-word-in-dictionary/ 题目描述 给出一个字符串数组words组成的一本英语词典.从中找出最 ...
- Leetcode 648.单词替换
单词替换 在英语中,我们有一个叫做 词根(root)的概念,它可以跟着其他一些词组成另一个较长的单词--我们称这个词为 继承词(successor).例如,词根an,跟随着单词 other(其他),可 ...
最新文章
- Python 笔试集(2):你不知道的 Python 整数
- 二叉树深度优先遍历和广度优先遍历
- mysql和sql互导_Mysql和SqlServer互相转换
- leaflet的入门开发(一)
- JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet
- OpenCV中Mat的属性
- 【渝粤教育】电大中专财务管理与分析 (2)作业 题库
- 前端学习(2818):小程序学习之新建页面
- LeetCode 727. 最小窗口子序列(滑动窗口)
- 什么样的程序员是最让人讨厌的?朋友们注意了,别做这种人!
- [开源]430驱动的12864图形点阵LCD
- 微服务架构工作笔记003---了解认识google Kubernetes 容器管理
- 我的Android学习之路
- 李彦宏谈无人车:高速上吃着火锅唱着歌,再有三五年能代替司机
- 每日算法系列【LeetCode 556】下一个更大元素 III
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)
- JavaScript数组forEach方法
- 酒店短视频营销,是酒店获客引流的重点推广手段之一
- 网络安全架构与域划分(企业安全)
- java if中的continue_java中break和continue源码解析