LeetCode 648. Replace Words 字典树练习

这篇博客介绍了如何利用字典树解决LeetCode中的648题,即用字典中能构成单词的最短前缀替换句子中的单词。在创建字典树时,将每个字符串的最后一个字符节点的val设为0,表示结束位置,遍历句子找到最短前缀进行替换。

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

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 theroot 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"

题意:用字典中存在的前缀代替句子中的单词,若有多个前缀可以表示单词,则选择最短的一个

用基础字典树即可解决,将字典中的前缀字符串存入字典树中,遍历每个句子的单词,找到最短的前缀返回即可

字典树结构:

struct Trie{
	int val;	//表示此位置是否有前缀结束
	vector<Trie*> child;
	Trie():child(vector<Trie*>(26,NULL)),val(-1){}
};

首先是字典树的创建(插入)过程,题目只要返回最短的前缀字符串,在插入时对于每一个字符串的最后一个字符节点的val设置为0表示此位置为结束位置。

void insert(string s,Trie* root){
	for(int i=0;i<s.size();i++){
		int num = s[i]-'a';
		if(root->child[num] == NULL)
		{
			root->child[num] = new Trie();
		}
		root = root->child[num];
        if(i!=s.size()-1&&root->val!=0)    	
            root->val = 1;
        else root->val = 0;	//若此位置为结束位置,将val设置为0
	}
}
   

查找时,遇到val为0的字符节点就可以返回,这样就能保证返回的前缀为最短的,若字典树中不存在此单词的前缀,那么查找停止位置的val不等于0;

    string search(string s,Trie* root){
	string res = "";
	for(int i=0;i<s.size();i++){
		int num = s[i] -'a';
		if(root->child[num] == NULL)
			break;
        root = root->child[num];
		    res += s[i];
        if(root->val == 0)
            return res;
		}
        if(root->val == 0)
	        return res;
        else return s;
}


在分割句子时可以使用强大的stringstream,将sentence先读入字符串流中,以空格为标示分割句子,超级方便,字符串分割利器,还能类型转化等等:

string replaceWords(vector<string>& dict, string sentence) {
        Trie *root = new Trie();
        string res = "";
        for(string s:dict)
            insert(s,root);
        stringstream ss(sentence);
        string s;
        int sign = 1;
        while(ss>>s){
            string temp = search(s,root);
            if(sign!=1)
                res += " ";
            if(temp.empty())
                res +=s;
            else res +=temp;
            sign++;
        }
        return res;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值