LeetCode每日一题:LeetCode 720. 词典中最长的单词

这篇博客介绍了三种不同的方法来解决LeetCode720题,即寻找字典中最长的单词。方法一采用暴力哈希,方法二利用排序和哈希,方法三使用字典树(Trie)。每种方法的时间复杂度和空间复杂度都有所不同,其中字典树方法在效率上更为优秀。博客深入探讨了这些算法的实现细节和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode 720. 词典中最长的单词

方法一:暴力哈希

存储每个单词哈希表中,检查每一个单词前缀是否都出现过,返回字典序最小长度最长的单词

时间复杂度: O ( n ∗ 30 ) O(n*30) O(n30)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n30)
class Solution {
public:
    set<string> S;
    string ans;
    bool check(string str) {
        for (int i = 1; i < str.size(); i ++ )
            if (!S.count(str.substr(0, i)))
                return false;
        return true;
    }
    string longestWord(vector<string>& words) {
        for (auto& s : words)
            S.insert(s);
        for (auto& s : words)
            if (check(s)) {
                if (ans.size() < s.size()) ans = s;
                else if (ans.size() == s.size() && ans > s) ans = s;
            }
        return ans;
    }
};

方法二:排序+哈希

时间复杂度: O ( n ∗ 30 ∗ l o g n ) O(n*30*logn) O(n30logn)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n30)
class Solution {
public:
    string longestWord(vector<string>& words) {
        sort(words.begin(), words.end(), [](const string & a, const string & b) {
            if (a.size() != b.size()) {
                return a.size() < b.size();
            } else {
                return a > b;
            }
        });
        string ans = "";
        unordered_set<string> cnt;
        cnt.insert("");
        for (auto & word : words) {
            if (cnt.count(word.substr(0, word.size() - 1))) {
                cnt.insert(word);
                ans = word;
            }
        }
        return ans;
    }
};

方法三:字典树

通过标记每一个结点id,遍历字典树找到有标记的最长的路径就是答案。

时间复杂度: O ( n ∗ 30 ) O(n*30) O(n30)
空间复杂度: O ( n ∗ 30 ) O(n*30) O(n30)
const int N = 30010;

int son[N][26], idx;
int id[N];

class Solution {
public:
    void insert(string& str, int k) {
        int p = 0;
        for (auto c: str) {
            int u = c - 'a';
            if (!son[p][u]) son[p][u] = ++ idx;
            p = son[p][u];
        }
        id[p] = k;
    }

    vector<int> dfs(int p, int len) {
        vector<int> res{len, id[p]};
        for (int i = 0; i < 26; i ++ ) {
            int j = son[p][i];
            if (j && id[j] != -1) {
                auto t = dfs(j, len + 1);
                if (res[0] < t[0]) res = t;
            }
        }
        return res;
    }

    string longestWord(vector<string>& words) {
        memset(id, -1, sizeof id);
        memset(son, 0, sizeof son);
        idx = 0;
        for (int i = 0; i < words.size(); i ++ ) insert(words[i], i);
        auto t = dfs(0, 0);
        if (t[1] != -1) return words[t[1]];
        return "";
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值