leetcode练习(前缀树数组实现)(java)

本文介绍了一种使用前缀树数据结构实现的英文单词替换算法,该算法能够在给定的词典中查找并替换句子中的继承词,用词根的最短形式替代较长的单词。通过构建前缀树,算法能够高效地分析每个单词,并找到其对应的最短词根。

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

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

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

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

示例 1:

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

输入只包含小写字母。
1 <= 字典单词数 <=1000
1 <= 句中词语数 <= 1000
1 <= 词根长度 <= 100
1 <= 句中词语长度 <= 1000
思路
用数组实现的前缀树作为数据结构

class Node{
		String str="";		//存放单词,如果是单词那么str就是对应的单词否则就是空字符串
		
		Node[] kids=new Node[26];	//26个英文字母对应26的结点数组
	}

我们可以分析实现将一个单词替换最短的前缀单词要对每个单词进行遍历。
对每个单词 对应前缀树的结点分析,如果结点是空表示没有以这个为前缀或者本身的单词可以直接考虑下一个单词,如果结点不是空考虑他str是空字符串否。如果str为空表示有以这个为前缀但不是本身的单词,我们继续对这个结点的26的子节点进行分析,如果对应的str是一个单词而非空字符串那么就是找到了最小前缀的单词,我们就将单词替换,在考虑下一单词或者结束。

import java.util.*;
class Solution {
	class Node{		//定义结点
		String str="";
		
		Node[] kids=new Node[26];
	}
	Node root=new Node();		//根节点
    public String replaceWords(List<String> dict, String sentence) {
        for(String str:dict) {		//将字典中的字符串插入到前缀树
        	Node node=root;			//从根节点开始
        	for(char c:str.toCharArray()) {
        		if(node.kids[c-'a']==null) {
        			node.kids[c-'a']=new Node();
        		}
        		node=node.kids[c-'a'];		//后移
        	}
        	node.str=str;		//找到字典中的字符串对应的结点,将这个结点str换成字典串
        }
        String[] strs=sentence.split(" ");	//将每个单词进行分割
        for(int i=0;i<strs.length;i++) {	//对每个单词一次分析替换
        	Node node=root;
        	for(char c:strs[i].toCharArray()) {
        		if(node.kids[c-'a']==null)	//没有通往这个单词的前缀
        			break;
        		else {
        			if(!node.kids[c-'a'].str.equals("")) {//找到最小前缀我们将语句中的单词进行替换
        				strs[i]=node.kids[c-'a'].str;
        				break;
        			}
        			node=node.kids[c-'a'];			//后移
        		}
        	}
        }
        StringBuilder str=new StringBuilder();	//连接字符串
        for(int i=0;i<strs.length;i++) {
        	if(i!=0)
        		str.append(" ");
        	str.append(strs[i]);
        }
        return str.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值