720. 词典中最长的单词 [中等]

878 阅读1分钟

题目

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

  • 来源:力扣(LeetCode)
  • 链接:leetcode.cn/problems/lo…
  • 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一

思路

  • 前缀树trie

注意:

  • 如果没有答案,需要返回空字符串,而不是null
  • 返回的最长的字符串需要是词典中其他单词逐步增加一个字母组成的。
  • 对于多个答案时,需要返回字典序最小的单词。
  • words = ["wo","wor","worl", "world"]
    • 就不存在最长的。因为"w"不在词典中
  • words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
    • banana就不是最长的

代码


class Solution {

    private String maxString = "";

    public String longestWord(String[] words) {
        Trie root = new Trie();
        // root的end标识默认为true
        root.end = true;
        for (String word : words) {
            root.insert(word);
        }

        visit(root);

        return maxString;
    }

    // 深度遍历
    private void visit(Trie root) {
        if (root == null || root.end == false) {
            return;
        }

        for (int i = 0; i < 26; i++) {
            Trie node = root.children[i];
            visit(node);
            if (node != null && node.end == true && node.value.length() > maxString.length()) {
                maxString = node.value;
            }
        }
    }

    private static class Trie {
        private Trie[] children;
        private boolean end;
        private String value;

        private Trie() {
            children = new Trie[26];
            end = false;
            value = null;
        }

        private void insert(String word) {
            int n = word.length();
            Trie[] children = this.children;
            for (int i = 0; i < n; i++) {
                char c = word.charAt(i);
                int index = c - 'a';
                Trie node = children[index];
                if (node == null) {
                    node = new Trie();
                    children[index] = node;
                }
                if (i == n-1) {
                    node.end = true;
                    node.value = word;
                }
                children = node.children;
            }
        }
    }
}

解法二

思路

  • 暴力解法
  • 长度为1的字符串肯定是自己的子串

代码

class Solution {
    public String longestWord(String[] words) {
        String res = "";
        for (String word : words) {
            if (res.length() < word.length() || (res.length() == word.length() && res.compareTo(word) > 0)) {
                boolean found = isSubString(words, word);
                if (found) {
                    res = word;
                }
            }
        }
        return res;
    }

    private boolean isSubString(String[] words, String target) {
        if (target.length() == 1) {
            return true;
        }
        for (int i = 1; i <= target.length(); i++) {
            String sub = target.substring(0, i);
            boolean found = false;
            for (String word : words) {
                if (word.equals(sub)) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                return false;
            }
        }
        return true;
    }
}