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:

  1. The input will only have lower-case letters.
  2. 1 <= dict words number <= 1000
  3. 1 <= sentence words number <= 1000
  4. 1 <= root length <= 100
  5. 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;
}
};

类似题目:

Implement Trie (Prefix Tree)

参考资料:

https://discuss.leetcode.com/topic/97203/trie-tree-concise-java-solution-easy-to-understand

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Replace Words 替换单词的更多相关文章

  1. MySQL replace函数替换字符串语句的用法(mysql字符串替换)

    MySQL replace函数我们经常用到,下面就为您详细介绍MySQL replace函数的用法,希望对您学习MySQL replace函数方面能有所启迪. 最近在研究CMS,在数据转换的时候需要用 ...

  2. sql server replace的替换字符,replace的使用

    sql server replace的替换字符,replace的使用 select REPLACE(name,'张','') * from entity_5c7a578c05c7042958d9148 ...

  3. js replace 全局替换

    js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换. <script language="j ...

  4. js replace全部替换的方法

    1.JS replace()方法替换变量(可以对变量进行全文替换) string.replace(new RegExp(key,'g'),"b"); 2.封装 String.pro ...

  5. js replace 全局替换 以表单的方式提交参数 判断是否为ie浏览器 将jquery.qqFace.js表情转换成微信的字符码 手机端省市区联动 新字体引用本地运行可以获得,放到服务器上报404 C#提取html中的汉字 MVC几种找不到资源的解决方式 使用Windows服务定时去执行一个方法的三种方式

    js replace 全局替换   js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换. <scrip ...

  6. 648. Replace Words 替换成为原来的单词

    [抄题]: In English, we have a concept called root, which can be followed by some other words to form a ...

  7. LeetCode Replace Words

    原题链接在这里:https://leetcode.com/problems/replace-words/description/ 题目: In English, we have a concept c ...

  8. eclipse怎么在项目里面批量替换单词

    先选中你要替换的东东,然后再菜单栏中找到Search→Text→Project(先创建要搜索的project),这样就会在整个项目中查找单词.然后在Search的Console中,单击项目,右键选择R ...

  9. ORACLE 利用 REPLACE函数替换字段字符串

    REPLACE(string,s1,s2) string 希望被替换的字符或变量 s1 被替换的字符串 s2 要替换的字符串 SQL> select replace(he love you,he ...

随机推荐

  1. WPF学习笔记2

    XML语言中添加注释为<!---->,这是和C#不同的,但是和HTML十分相似. XAML是一种基于XML的标记语言,每一个XML元素代表.NET控件的一个对象,XML元素的属性可以是.N ...

  2. QQ数据库管理

    1,数据库关系图 ##用例1:查询数据 #01.查询QQ号码为54789625的所有好友信息,包括QQ号码,昵称,年龄 select RelationQQID as QQ号码,NickName as ...

  3. SpringMVC参数校验

    使用SpringMVC时配合hibernate-validate进行参数的合法性校验,能节省一定的代码量. 使用步骤 1.搭建Web工程并引入hibernate-validate依赖 <depe ...

  4. JavaWeb学习笔记七 事务

    什么是事务?一件事情有n个组成单元 ,要么这n个组成单元同时成功,要么n个单元就同时失败.就是将n个组成单元放到一个事务中. mysql的事务 默认的事务:一条sql语句就是一个事务,默认就开启事务并 ...

  5. 【Alpha】咸鱼冲刺日记第一天-黄紫仪

    总汇链接 一,合照 emmmmm.自然是没有的. 二,项目燃尽图 emmmmm,事实上它还没有正式开始.所以依旧没有[突然觉得明天任务真重] 三,项目进展 emmmmm,我错了咸鱼了两天才突然反应过来 ...

  6. 2018C程序设计—第0次作业

    1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题,每个问题的答案不少于500字 1)最理想的师生关系是健身教练和学员的关系,在这种师生关系中你期望获得来自老师的哪些帮助? 答:正如邹欣老师博客里所 ...

  7. JAVA_SE基础——62.String类的构造方法

    下面我先列出初学者目前用到的构造方法 String 的构造方法:     String()  创建一个空内容 的字符串对象.   String(byte[] bytes)  使用一个字节数组构建一个字 ...

  8. python实现维吉尼亚解密

    # -*-coding:UTF-8-*- from sys import stdout miwen = "KCCPKBGUFDPHQTYAVINRRTMVGRKDNBVFDETDGILTXR ...

  9. js进度条小事例

    <style> #div1{width: 500px;height: 20px;border: 1px solid gray;} #div2{height: 20px;width: 0px ...

  10. AngularJS1.X学习笔记13-动画和触摸

    本文主要涉及了ngAnimation和ngTouch模块,自由男人讲的比较少,估计要用的时候还要更加系统的学习一下. 一.安装 没错,就是酱紫. 二.玩玩动画 <!DOCTYPE html> ...