[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].

    思路

    1、哈希表法:我们定义一个哈希表,用来存储已找到所有前缀的字符串。然后对原来的字符串数组进行排序(这样每个字符串的前缀就会先于字符串本身被找出)。接着处理每一个字符串:如果该字符串的上一个前缀已经存在于哈希表中,则更新ret,并将该字符串也加入哈希表中。

    算法的时间复杂度是O(nlogn),空间复杂度是O(n)。

    2、字典树法:基本思路和哈希表是一致的,只不过我们用字典树存储所有的字符串。在对字符串数组进行排序之后,我们逐个检查字符串。只有当字符串的最大前缀已经存在于字典树中,我们才将该字符串加入字典树中,并更新ret。

    代码

    1、哈希表法:

    class Solution {
    public:
        string longestWord(vector<string>& words) {
            unordered_set<string> hash;
            hash.insert("");
            sort(words.begin(), words.end());
            string ret;
            for (auto s : words) {
                if(hash.count(s.substr(0, s.length() - 1)) > 0) {
                    if (s.length() > ret.length()) {
                        ret = s;
                    }
                    hash.insert(s);
                }
            }
            return ret;
        }
    };

    2、字典树法:

    class Solution {
    public:
        string longestWord(vector<string>& words) {
            root = new TrieNode();
            string ret;
            sort(words.begin(), words.end());
            for (auto &s : words) {
                TrieNode *node = root;
                int i = 0;
                for (; i + 1 < s.length(); ++i) {
                    int index = s[i] - 'a';
                    if (node->children[index] == NULL) {
                        break;
                    }
                    node = node->children[index];
                }
                if (i + 1 == s.length()) {
                    int index = s[i] - 'a';
                    node->children[index] = new TrieNode();
                    node = node->children[index];
                    if (ret.length() < s.length()) {
                        ret = s;
                    }
                }
            }
            return ret;
        }
    private:
        struct TrieNode {
            vector<TrieNode*> children;
            TrieNode() {
                children = vector<TrieNode*>(26, NULL);
            }
        };
        TrieNode* root;
    };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值