面试算法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);
    }
}

你可能感兴趣的:(算法,面试,算法,windows)