Leetcode--Java--648. 单词替换

使用字典树解决LeetCode第648题,将句子中的继承词替换为最短词根。通过构建前缀树并在树中查找最短词根,对输入句子进行处理。

题目描述

在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。
现在,给定一个由许多词根组成的词典 dictionary 和一个用空格分隔单词形成的句子 sentence。你需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
你需要输出替换之后的句子。

样例描述

示例 1:

输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"
示例 2:

输入:dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
输出:"a a b c"

思路

字典树 (前缀树,trie树)

  1. 在trie树的模板上稍加修改(将原来用于判断是否是结尾的改成记录词根,并且仅仅存在词根的最后一个字母),将词根挂在树上,用每个词根的最后一个字母结点的变量来存储词根
  2. split("\s+")万能的分隔

代码

class TrieNode {
    TrieNode tns[];
    String word;//记录词根
    public TrieNode() {
        tns = new TrieNode[26];
    }
}
class Solution {
    public String replaceWords(List<String> dictionary, String sentence) {
        TrieNode trie = new TrieNode();
        //构造trie树,将词根插入到树上,并且在每个词根最后一个字母处记录该词根
        //基于trie树的插入部分代码
        for (String root: dictionary) {
            TrieNode cur = trie;
            for (char c: root.toCharArray()) {
                int u = c - 'a';
                if (cur.tns[u] == null) {
                    cur.tns[u] = new TrieNode();
                }
                cur = cur.tns[u];
            }
            cur.word = root;
        }
        StringBuilder res = new StringBuilder();
        //也可以用split("//s+")表示以空格,逗号等作为分隔,类似*的作用
        String[] sentens = sentence.split(" ");
        for (String s: sentens) {
            //注意用空格技巧,要使得首部或者尾部不能有额外的空格
           if (res.length() > 0) {
               res.append(' ');
           }
            TrieNode cur = trie;
            for (char c: s.toCharArray()) {
                int u = c - 'a';
                //如果当前父母不在树上,或者已经找到了词根
                if (cur.tns[u] == null || cur.word != null) {
                    break;
                }
                cur = cur.tns[u];
            }
            if (cur.word != null) {
                res.append(cur.word);
            } else {
                res.append(s);
            }
        }
        return res.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值