单词替换
在英语中,我们有一个叫做 词根(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();
}
}