热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LeetCode648.使用Trie树实现单词替换

本问题探讨了如何利用词根(root)概念在英文中构建继承词(successor)。具体来说,通过给定的一系列词根和一个句子,任务是使用词根替换句子中的继承词,以形成一个新的句子。

问题描述

在英语语言学中,存在一个称为词根(root)的概念,它能够与其它词汇组合形成新的、更长的词汇——这类新形成的词汇被定义为继承词(successor)。例如,词根'an'与单词'other'结合,可以生成新词'another'。

本题提供了一个词根列表和一个句子。目标是将句子中所有的继承词替换为其对应的词根。若一个继承词可由多个词根构成,则选择最短的那个词根进行替换。最终需要返回经过替换后的句子。

示例输入: 词根列表 = ["cat", "bat", "rat"]
句子 = "the cattle was rattled by the battery"
期望输出: "the cat was rat by the bat"
限制条件:
输入仅包含小写字母。
词根列表的长度范围为1至1000。
句子中的单词数量不超过1000个。
单个词根的最大长度为100。
句子中单词的最大长度为1000。

Trie树解决方案

此问题可以通过构建Trie树来高效解决。首先,将所有的词根插入到Trie树中;接着,对于句子中的每一个单词,检查其所有可能的前缀是否存在于Trie树中,如果存在,则使用该前缀(即词根)替换原单词。

以下是C++实现代码示例:

class TrieNode {
public:
char value;
bool isWord;
TrieNode* children[26];
TrieNode(char val): value(val), isWord(false) {
memset(children, 0, sizeof(children));
}
};

class Trie {
private:
TrieNode* root;
public:
Trie() { root = new TrieNode('/0'); }
~Trie() { destroy(root); }
void destroy(TrieNode* node) {
for (int i = 0; i <26; ++i) {
if (node->children[i]) destroy(node->children[i]);
}
delete node;
}
void insert(const std::string& word) {
TrieNode* current = root;
for (char c : word) {
if (!current->children[c - 'a']) {
current->children[c - 'a'] = new TrieNode(c);
}
current = current->children[c - 'a'];
}
current->isWord = true;
}
std::string searchPrefix(const std::string& word) {
TrieNode* current = root;
std::string prefix;
for (char c : word) {
if (!current->children[c - 'a']) return "";
current = current->children[c - 'a'];
prefix += c;
if (current->isWord) return prefix;
}
return "";
}
};

class Solution {
public:
std::string replaceWords(std::vector& dictionary, std::string sentence) {
Trie trie;
for (const std::string& root : dictionary) {
trie.insert(root);
}
std::stringstream ss(sentence);
std::string word, result;
while (ss >> word) {
std::string prefix = trie.searchPrefix(word);
result += (prefix.empty() ? word : prefix) + " ";
}
if (!result.empty()) result.pop_back();
return result;
}
};

推荐阅读
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 本文介绍如何使用 Python 将一个字符串按照指定的行和元素分隔符进行两次拆分,最终将字符串转换为矩阵形式。通过两种不同的方法实现这一功能:一种是使用循环与 split() 方法,另一种是利用列表推导式。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 本文详细介绍了C语言中链表的两种动态创建方法——头插法和尾插法,包括具体的实现代码和运行示例。通过这些内容,读者可以更好地理解和掌握链表的基本操作。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
author-avatar
加州旅馆在南京_380
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有