面试算法63:替换单词

题目

英语中有一个概念叫词根。在词根后面加上若干字符就能拼出更长的单词。例如,“an"是一个词根,在它后面加上"other"就能得到另一个单词"another”。现在给定一个由词根组成的字典和一个英语句子,如果句子中的单词在字典中有它的词根,则用它的词根替换该单词;如果单词没有词根,则保留该单词。请输出替换后的句子。
例如,如果词根字典包含字符串[“cat”,“bat”,“rat”],英语句子为"the cattle was rattled by the battery",则替换之后的句子是"the cat was rat by the bat"。

分析

题目中的词根其实就是前缀,因此很容易想到用前缀树来解决。用前缀树解决问题通常分为两步,第1步是创建前缀树,第2步是在前缀树中查找。

public class Test {
   
    public static void main(String[] args) {
   
        List<String> dict = Arrays.asList("cat", "bat", "rat");
        String sentence = "the cattle was rattled by the battery";
        String result = replaceWords(dict, sentence);
        System.out.println(result);
    }

    static class TrieNode {
   
        boolean isWord;
        TrieNode[] children;

        public TrieNode() {
   
            isWord = false;
            children = new TrieNode[26];
        }
    }

    private static 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 static 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 static 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);
    }
}

相关推荐

  1. 面试算法63替换单词

    2023-12-21 13:10:03       40 阅读
  2. 面试算法65:最短的单词编码

    2023-12-21 13:10:03       38 阅读
  3. 面试算法-63-全排列

    2023-12-21 13:10:03       17 阅读
  4. 面试算法-99-单词拆分

    2023-12-21 13:10:03       16 阅读
  5. 面试算法-128-单词拆分 II

    2023-12-21 13:10:03       11 阅读
  6. 算法63单调栈3

    2023-12-21 13:10:03       13 阅读
  7. 面试算法-64-零钱兑换

    2023-12-21 13:10:03       18 阅读
  8. 面试算法62:实现前缀树

    2023-12-21 13:10:03       34 阅读
  9. 程序设计——单词的统计和替换

    2023-12-21 13:10:03       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-21 13:10:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-21 13:10:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-21 13:10:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-21 13:10:03       18 阅读

热门阅读

  1. 在spring boot项目引入mybatis plus后的的案例实践

    2023-12-21 13:10:03       44 阅读
  2. Rust中Result处理方式

    2023-12-21 13:10:03       33 阅读
  3. 力扣题目学习笔记(OC + Swift)16. 最接近的三数之和

    2023-12-21 13:10:03       41 阅读
  4. Python多任务编程-07多线程版udp聊天程序

    2023-12-21 13:10:03       27 阅读
  5. shell——变量之字符串的截取

    2023-12-21 13:10:03       33 阅读
  6. Vue的网络请求、插槽、Vuex

    2023-12-21 13:10:03       44 阅读
  7. git或svn提交消息时,fix、feat等命令的含义

    2023-12-21 13:10:03       41 阅读
  8. 爬虫scrapy管道的使用

    2023-12-21 13:10:03       34 阅读
  9. 面试经典150题(38-41)

    2023-12-21 13:10:03       33 阅读