剑指offer63:替换单词

题目:
在英语中,有一个叫做 词根(root) 的概念,它可以跟着其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。
现在,给定一个由许多词根组成的词典和一个句子,需要将句子中的所有继承词用词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。
需要输出替换之后的句子。
输入:dictionary = [“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”
输入:dictionary = [“a”,“b”,“c”], sentence = “aadsfasf absbs bbab cadsfafs”
输出:“a a b c”
输入:dictionary = [“catt”,“cat”,“bat”,“rat”], sentence = “the cattle was rattled by the battery”
输出:“the cat was rat by the bat”
分析:
题目中要求前缀替换句子中的单词,首先需要找到单词中的前缀,可以用前缀树解决这个问题,创建前缀树的过程就是将字典中的单词逐个添加到前缀树中,在前缀树中查找单词的前缀,即从前缀树的根节点出发,逐个判读节点是否有子节点与单词的字符对应,如果查找过程中遇到一个isWord标记为true的节点,那么就找到了单词的前缀,最后还得考虑如何替换句子中的单词,英语使用空格作为分隔符,因此可以根据空格将句子分隔成若干个单词,通过前缀树查找分隔出来的每个单词的前缀,如果找到单词前缀则用前缀代替该单词。
代码:

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    static class TrieNode{
        TrieNode children[];
        boolean isword;
        public TrieNode(){
            children = new TrieNode[26];
        }
    }
    //    创建前缀树
    private TrieNode buildTrie(List<String> dict){
        TrieNode root = new TrieNode();
        for (String word : dict) {
            TrieNode node = root;
            for (char ch: word.toCharArray()){
//                判断该节点的孩子节点是否为空,如果为空接着填充,不为空则接着深入下一个孩子节点,直到遍历完
                if (node.children[ch - 'a'] == null){
                    node.children[ch - 'a'] = new TrieNode();
                }
                node = node.children[ch - 'a'];
            }
            node.isword = true;
        }
        return root;
    }
    //    需要去找出单词的前缀
    private String findPrefix(TrieNode root, String word){
        TrieNode node = root;
        StringBuilder builder = new StringBuilder();
        for (char ch:word.toCharArray()){
            if (node.isword || node.children[ch-'a'] == null){
                break;
            }
            builder.append(ch);
            node = node.children[ch - 'a'];
        }
        return node.isword ?builder.toString() : "";
    }
    public String replaceWords(List<String> dict,String sentence){
    //建立前缀树
        TrieNode root = buildTrie(dict);
//        先将长字符串处理一下
        StringBuilder builder = new StringBuilder();
//        将字符串中的单词通过空格来分离返回字符串数组
        String[] words = sentence.split(" ");
//        对数组进行遍历,并查找数组中的字符串是否包含字典当中的前缀
        for (int i = 0; i < words.length; i++) {
            String prefix = findPrefix(root, words[i]);
//如果返回的字符串不为空,就可以让前缀替换掉单词了
            if (!prefix.isEmpty()){
                words[i] = prefix;
            }
        }
        //全部替换完后,将字符串数组整合回一个字符串
        return String.join(" ",words);
    }
}



在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙崎流河

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值