• [LeetCode] 720. Longest Word in Dictionary


    Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order.

    If there is no answer, return the empty string.

    Example 1:

    Input: 
    words = ["w","wo","wor","worl", "world"]
    Output: "world"
    Explanation: 
    The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".

    Example 2:

    Input: 
    words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
    Output: "apple"
    Explanation: 
    Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply".

    Note:

    • All the strings in the input will only contain lowercase letters.
    • The length of words will be in the range [1, 1000].
    • The length of words[i] will be in the range [1, 30].

    词典中最长的单词。题意是给出一个字符串数组words组成的一本英语词典。从中找出最长的一个单词,该单词是由words词典中其他单词逐步添加一个字母组成。若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

    我提供两种做法,一种暴力,一种是字典树 + BFS。

    首先是暴力解,我们需要一个hashset记录单词。注意Arrays.sort()是可以对字母/单词排序的,所以我们用这个函数先对input array进行排序,这样字典序较小的单词会靠前。此时我们再次扫描input array,遍历每个单词,把每个单词加入一个hashset。加入之前判断

    这个单词的长度是否为1 或者 hashset里面已经存在了这个单词除去最后一个字母的前缀(比如abc的话,我们去检查一下hashset里是否有ab)。这两个条件只要满足一个,就可以更新res的长度。

    单词长度为1的话,只能是有一个空的前缀,但是越晚出现的单个字母,其字典序应该更大。这也就是为什么出现单个字母我们也需要更新res的原因。

    时间O(n)

    空间O(n) - hashset

    Java实现

     1 class Solution {
     2     public String longestWord(String[] words) {
     3         Arrays.sort(words);
     4         HashSet<String> built = new HashSet<String>();
     5         String res = "";
     6         for (String w : words) {
     7             if (w.length() == 1 || built.contains(w.substring(0, w.length() - 1))) {
     8                 res = w.length() > res.length() ? w : res;
     9                 built.add(w);
    10             }
    11         }
    12         return res;
    13     }
    14 }

    再来是字典树 + BFS的做法。这里我们还是自己写一个node class表示节点,其中有两个参数,一个是长度为26的数组表示字母,一个是最后node组成的单词word。遍历input数组,把每个单词都做成一个字典树的node。之后通过BFS的方式遍历queue中所有的node,返回字典序最小的结果。

    时间O(n)

    空间O(n) - node class

    Java实现

     1 class Solution {
     2     // 字典树节点,每个节点代表一个字母
     3     class Node {
     4         // 该节点的下一个字母
     5         Node[] children = new Node[26];
     6         // 如果是单词结尾,保存该单词,否则为空
     7         String word;
     8     }
     9 
    10     // 定义字典树根节点
    11     Node root = new Node();
    12 
    13     public String longestWord(String[] words) {
    14         // 根节点默认单词为空
    15         root.word = "";
    16         // 将每一个单词加入字典树
    17         for (String s : words) {
    18             Node node = root;
    19             for (int i = 0; i < s.length(); i++) {
    20                 int c = s.charAt(i) - 'a';
    21                 if (node.children[c] == null) {
    22                     node.children[c] = new Node();
    23                 }
    24                 node = node.children[c];
    25             }
    26             // 单词结尾时,将该单词保存至当前节点中
    27             node.word = s;
    28         }
    29         // bfs
    30         Queue<Node> q = new LinkedList<>();
    31         // bfs起点
    32         q.offer(root);
    33         // 返回结果
    34         String res = "";
    35         while (q.size() > 0) {
    36             int size = q.size();
    37             // 当前长度下字典顺序最小的单词
    38             String smallestValid = "";
    39             while (size > 0) {
    40                 size--;
    41                 Node n = q.poll();
    42                 // 记录当前长度下字典顺序最小的单词
    43                 if ("".equals(smallestValid)) {
    44                     smallestValid = n.word;
    45                 }
    46                 Node[] children = n.children;
    47                 for (int i = 0; i < 26; i++) {
    48                     // 如果子节点为空,或者子节点不是单词结尾,跳过
    49                     if (children[i] == null || children[i].word == null) {
    50                         continue;
    51                     }
    52                     // 将子节点添加到Queue中(子节点为下一个长度的单词)
    53                     q.offer(children[i]);
    54                 }
    55             }
    56             // 当前长度遍历完之后,将字典顺序最小的一个保存至返回结果
    57             res = smallestValid;
    58         }
    59         return res;
    60     }
    61 }

    相关题目

    392. Is Subsequence

    524. Longest Word in Dictionary through Deleting

    720. Longest Word in Dictionary

    LeetCode 题目总结

  • 相关阅读:
    二维码
    struts2 result type=(chain、dispatcher、redirect、redirect-action)
    hibernate bean注解
    js uploadify
    2进制转化成字符串
    server.xml
    html css
    页面乱码
    java class 路径问题
    table th td 宽度
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13896518.html
Copyright © 2020-2023  润新知