[LeetCode] Replace Words 替换单词
In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another.
Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length.
You need to output the sentence after the replacement.
Example 1:
Input: dict = ["cat", "bat", "rat"]
sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"
Note:
- The input will only have lower-case letters.
- 1 <= dict words number <= 1000
- 1 <= sentence words number <= 1000
- 1 <= root length <= 100
- 1 <= sentence words length <= 1000
这道题给了我们一个前缀字典,又给了一个句子,让我们将句子中较长的单词换成其前缀(如果在前缀字典中存在的话)。我们对于句子中的一个长单词如何找前缀呢,是不是可以根据第一个字母来快速定位呢,比如cattle这个单词的首字母是c,那么我们在前缀字典中找所有开头是c的前缀,为了方便查找,我们将首字母相同的前缀都放到同一个数组中,总共需要26个数组,所以我们可以定义一个二维数组来装这些前缀。还有,我们希望短前缀在长前缀的前面,因为题目中要求用最短的前缀来替换单词,所以我们可以先按单词的长度来给所有的前缀排序,然后再依次加入对应的数组中,这样就可以保证短的前缀在前面。
下面我们就要来遍历句子中的每一个单词了,由于C++中没有split函数,所以我们就采用字符串流来提取每一个单词,对于遍历到的单词,我们根据其首字母查找对应数组中所有以该首字母开始的前缀,然后直接用substr函数来提取单词中和前缀长度相同的子字符串来跟前缀比较,如果二者相等,说明可以用前缀来替换单词,然后break掉for循环。别忘了单词之前还要加上空格,参见代码如下:
解法一:
class Solution {
public:
string replaceWords(vector<string>& dict, string sentence) {
string res = "", t = "";
vector<vector<string>> v();
istringstream is(sentence);
sort(dict.begin(), dict.end(), [](string &a, string &b) {return a.size() < b.size();});
for (string word : dict) {
v[word[] - 'a'].push_back(word);
}
while (is >> t) {
for (string word : v[t[] - 'a']) {
if (t.substr(, word.size()) == word) {
t = word;
break;
}
}
res += t + " ";
}
res.pop_back();
return res;
}
};
你以为想出了上面的解法,这道题就算做完了?? Naive! ! ! 这道题最好的解法其实是用前缀树(Trie / Prefix Tree)来做,关于前缀树使用之前有一道很好的入门题Implement Trie (Prefix Tree)。了解了前缀树的原理机制,那么我们就可以发现这道题其实很适合前缀树的特点。我们要做的就是把所有的前缀都放到前缀树里面,而且在前缀的最后一个结点的地方将标示isWord设为true,表示从根节点到当前结点是一个前缀,然后我们在遍历单词中的每一个字母,我们都在前缀树查找,如果当前字母对应的结点的表示isWord是true,我们就返回这个前缀,如果当前字母对应的结点在前缀树中不存在,我们就返回原单词,这样就能完美的解决问题了。所以啊,以后遇到了有关前缀或者类似的问题,一定不要忘了前缀树这个神器哟~
解法二:
class Solution {
public:
class TrieNode {
public:
bool isWord;
TrieNode *child[];
TrieNode(): isWord(false) {
for (auto &a : child) a = NULL;
}
};
string replaceWords(vector<string>& dict, string sentence) {
string res = "", t = "";
istringstream is(sentence);
TrieNode *root = new TrieNode();
for (string word : dict) {
insert(root, word);
}
while (is >> t) {
if (!res.empty()) res += " ";
res += findPrefix(root, t);
}
return res;
}
void insert(TrieNode* node, string word) {
for (char c : word) {
if (!node->child[c - 'a']) node->child[c - 'a'] = new TrieNode();
node = node->child[c - 'a'];
}
node->isWord = true;
}
string findPrefix(TrieNode* node, string word) {
string cur = "";
for (char c : word) {
if (!node->child[c - 'a']) break;
cur.push_back(c);
node = node->child[c - 'a'];
if (node->isWord) return cur;
}
return word;
}
};
类似题目:
参考资料:
https://discuss.leetcode.com/topic/97203/trie-tree-concise-java-solution-easy-to-understand
[LeetCode] Replace Words 替换单词的更多相关文章
- MySQL replace函数替换字符串语句的用法(mysql字符串替换)
MySQL replace函数我们经常用到,下面就为您详细介绍MySQL replace函数的用法,希望对您学习MySQL replace函数方面能有所启迪. 最近在研究CMS,在数据转换的时候需要用 ...
- sql server replace的替换字符,replace的使用
sql server replace的替换字符,replace的使用 select REPLACE(name,'张','') * from entity_5c7a578c05c7042958d9148 ...
- js replace 全局替换
js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换. <script language="j ...
- js replace全部替换的方法
1.JS replace()方法替换变量(可以对变量进行全文替换) string.replace(new RegExp(key,'g'),"b"); 2.封装 String.pro ...
- js replace 全局替换 以表单的方式提交参数 判断是否为ie浏览器 将jquery.qqFace.js表情转换成微信的字符码 手机端省市区联动 新字体引用本地运行可以获得,放到服务器上报404 C#提取html中的汉字 MVC几种找不到资源的解决方式 使用Windows服务定时去执行一个方法的三种方式
js replace 全局替换 js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换. <scrip ...
- 648. Replace Words 替换成为原来的单词
[抄题]: In English, we have a concept called root, which can be followed by some other words to form a ...
- LeetCode Replace Words
原题链接在这里:https://leetcode.com/problems/replace-words/description/ 题目: In English, we have a concept c ...
- eclipse怎么在项目里面批量替换单词
先选中你要替换的东东,然后再菜单栏中找到Search→Text→Project(先创建要搜索的project),这样就会在整个项目中查找单词.然后在Search的Console中,单击项目,右键选择R ...
- ORACLE 利用 REPLACE函数替换字段字符串
REPLACE(string,s1,s2) string 希望被替换的字符或变量 s1 被替换的字符串 s2 要替换的字符串 SQL> select replace(he love you,he ...
随机推荐
- 透析thinkphp5升级版开发框架tpframe
这里将全面的介绍这个框架给我们开发带来的好处,让你们对它有更深层次的认识,喜欢或不喜欢的,欢迎大家前来留言讨论 一.目录层次结构 现在很多的项目,特别是大一点的项目里面,都会有很多的人参与,要进行程序 ...
- curl 获取外网IP
#curl http://members.3322.org/dyndns/getip121.204.134.10
- machine learning 之 多元线性回归
整理自Andrew Ng的machine learning课程 week2. 目录: 多元线性回归 Multivariates linear regression /MLR Gradient desc ...
- 高级软件工程2017第5次作业—— 团队项目:需求改进&系统设计
Deadline:2017-10-23(周一) 21:00pm 注:以下内容参考 集大作业 1.评分规则: 按时交 - 有分,检查的项目包括后文的四个方面 需求&原型改进 - 20分 系统设计 ...
- 简易web服务器
当通过Socket开发网络应用程序的时候,首先需要考虑所使用的网络类型,主要包括以下三个方面: 1)Socket类型,使用网络协议的类别,如IPv4的类型为PF_INET. 2)数据通信的类型,常见的 ...
- 201621123040《Java程序设计》第3周学习总结
1.本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词,如类.对象.封装等 面向对象的思想 对象 类 1.2 用思维导图或者Onenote或其他工具将这些关键词组织起来. 掌握的还不够深 ...
- V7000数据恢复(存储文件系统损坏)案例_北亚数据恢复
我们今天介绍的数据恢复案例是一起 v7000存储文件系统损坏导致的数据丢失,首先简单介绍一下设备基本情况:发生文件系统损坏的是一台挂载在Windows2003服务器上的v7000存储,划分了一个容量为 ...
- 《javascript设计模式与开发实践》阅读笔记(10)—— 组合模式
组合模式:一些子对象组成一个父对象,子对象本身也可能是由一些孙对象组成. 有点类似树形结构的意思,这里举一个包含命令模式的例子 var list=function(){ //创建接口对象的函数 ret ...
- SpringCloud应用入库后乱码问题
一.现象 1.请求 2.入库后 二.解决过程 1.配置application.properties 2.代码配置 3.数据库(关键!!) 3.请求 三.验证过程 1.win10 - 本地验证通过 2. ...
- SLF4J - 一个允许你统一日志记录API的抽象层
一.什么是SLF4J 我们在做Java开发时,如果需要记录日志,有很多日志API可供选择,如: java.util.logging Apache log4j logback SLF4J又是个什么东东呢 ...