LeetCode 648: 单词替换

这篇博客介绍了LeetCode 648问题,即如何使用词根替换句子中的继承词。文章提供了两种解决方案,一是利用unordered_set容器存储词根并逐个单词匹配,二是通过构建前缀树实现快速查找和替换,从而提高效率。示例展示了如何将原句"the cattle was rattled by the battery"替换为"the cat was rat by the bat"。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode 648: 单词替换

题目描述

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

现在,给定一个由许多词根组成的词典和一个句子。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

你需要输出替换之后的句子。

示例:

输入:dict(词典) = [“cat”, “bat”, “rat”] sentence(句子) = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”

提示:

输入只包含小写字母。
1 <= dict.length <= 1000
1 <= dict[i].length <= 100
1 <= 句中词语数 <= 1000
1 <= 句中词语长度 <= 1000

解题

unordered_set

    将词典中的单词存放在一个unordered_set容器中,对于要替换的句子,只需要在该容器中查找是否有对应的词根,如果有则替换原有单词,这一过程可以将整个句子拆分成若干个单词,逐个单词进行匹配,也可以逐字符匹配,下面是使用逐字符匹配的方式。

class Solution {
public:
    string replaceWords(vector<string>& dict, string sentence) {
        unordered_set<string> roots(dict.begin(), dict.end());
        string s_out;
        for (int i=0; i< sentence.size(); ++i){
            if (sentence[i]==' ') continue;
            string cur_word;
            while (i < sentence.size() && sentence[i]!= ' ' && roots.find(cur_word)==roots.end()){
                cur_word += sentence[i];
                ++i;
            }
            while (i < sentence.size() && sentence[i]!=' ') ++i;
            s_out += cur_word;
            if (i < sentence.size()) s_out += ' ';
        }
        return s_out;
    }
};
前缀树

    这道题目是在前缀树专栏中出现的,说明了前缀树可以存储字符串和快速查找的实际应用。什么是前缀树,可以看LeetCode前缀树,这里简单说,前缀树就是N叉树的特殊形式。这里使用前缀树来代替unordered_set完成快速储存和查找功能。

class Solution {
public:
    string replaceWords(vector<string>& dict, string sentence) {
        root = new nNode;
        for (auto &s : dict){
            nNode *cur_node = root;
            for (auto &c : s){
                if (cur_node->is_root) break;
                if (cur_node->childs[c-'a']==NULL)
                    cur_node->childs[c-'a']=new nNode;
                   
                cur_node = cur_node->childs[c-'a'];
            }
            cur_node->is_root = true;
        }

        string s_out;
        istringstream i_str_stream(sentence);
        string cur_str;
        while (i_str_stream >> cur_str){
            if (!s_out.empty()) s_out += ' ';
            s_out += change_curstr(cur_str);
        }
        return s_out;
    }

private:
    struct nNode{
        bool is_root = false;
        nNode *childs[26] = {NULL};
    } *root;

    string change_curstr(string &str){
        string cur_str;
        nNode *cur_node = root;
        for (auto s : str){
            if (cur_node->childs[s-'a'] == NULL) return str;
            cur_str += s;
            cur_node = cur_node->childs[s-'a'];
            if (cur_node->is_root) break;
        }
        return cur_str;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值