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

这道题给了我们一个字典,是个字符串数组,然后问我们从单个字符开始拼,最长能组成啥单词,注意中间生成的字符串也要在字典中存在,而且当组成的单词长度相等时,返回字母顺序小的那个。好,看到这么多前缀一样多字符串,是不是很容易想到用前缀树来做,其实我们并不需要真正的建立前缀树结点,可以借鉴查找的思想来做。那么为了快速的查找某个单词是否在字典中存在,我们将所有单词放到哈希集合中,在查找的时候,可以采用BFS或者DFS都行。先来看BFS的做法,使用一个queue来辅助,我们先把所有长度为1的单词找出排入queue中,当作种子选手,然后我们进行循环,每次从队首取一个元素出来,如果其长度大于我们维护的最大值mxLen,则更新mxLen和结果res,如果正好相等,也要更新结果res,取字母顺序小的那个。然后我们试着增加长度,做法就是遍历26个字母,将每个字母都加到单词后面,然后看是否在字典中存在,存在的话,就加入queue中等待下一次遍历,完了以后记得要恢复状态,参见代码如下:

解法一:

class Solution {
public:
string longestWord(vector<string>& words) {
string res = "";
int mxLen = ;
unordered_set<string> s(words.begin(), words.end());
queue<string> q;
for (string word : words) {
if (word.size() == ) q.push(word);
}
while (!q.empty()) {
string t = q.front(); q.pop();
if (t.size() > mxLen) {
mxLen = t.size();
res = t;
} else if (t.size() == mxLen) {
res = min(res, t);
}
for (char c = 'a'; c <= 'z'; ++c) {
t.push_back(c);
if (s.count(t)) q.push(t);
t.pop_back();
}
}
return res;
}
};

下面来看递归的解法,前面都一样,不同在于直接对长度为1的单词调用递归函数,在递归中,还是先判断单词和mxLen关系来更新结果res,然后就是遍历所有字符,加到单词后面,如果在集合中存在,调用递归函数,结束后恢复状态,参见代码如下:

解法二:

class Solution {
public:
string longestWord(vector<string>& words) {
string res = "";
int mxLen = ;
unordered_set<string> s(words.begin(), words.end());for (string word : words) {
if (word.size() == ) helper(s, word, mxLen, res);
}
return res;
}
void helper(unordered_set<string>& s, string word, int& mxLen, string& res) {
if (word.size() > mxLen) {
mxLen = word.size();
res = word;
} else if (word.size() == mxLen) {
res = min(res, word);
}
for (char c = 'a'; c <= 'z'; ++c) {
word.push_back(c);
if (s.count(word)) helper(s, word, mxLen, res);
word.pop_back();
}
}
};

下面这种解法是论坛上的高分解法,其实我们只要给数组排个序,就可以使用贪婪算法来做了,并不需要什么DFS或BFS这么复杂。首先建立一个空的哈希set,然后我们直接遍历排序后的字典,对于当前的单词,如果当前单词长度为1,或者该单词去掉最后一个字母后在集合中存在,这也不难理解,长度为1,说明是起始单词,不需要的多余的判断,否则的话就要判断其去掉最后一个字母后的单词是否在集合中存在,存在的话,才说明其中间单词都存在,因为此时是从短单词向长单词遍历,只要符合要求的才会加入集合,所以一旦其去掉尾字母的单词存在的话,那么其之前所有的中间情况都会在集合中存在。我们更新结果res时,要判断当前单词长度是否大于结果res的长度,因为排序过后,默认先更新的字母顺序小的单词,所有只有当当前单词长度大,才更新结果res,之后别忘了把当前单词加入集合中,参见代码如下:

解法三:

class Solution {
public:
string longestWord(vector<string>& words) {
string res = "";
unordered_set<string> s;
sort(words.begin(), words.end());
for (string word : words) {
if (word.size() == || s.count(word.substr(, word.size() - ))) {
res = (word.size() > res.size()) ? word : res;
s.insert(word);
}
}
return res;
}
};

类似题目:

Longest Word in Dictionary through Deleting

Implement Magic Dictionary

参考资料:

https://discuss.leetcode.com/topic/109643/java-c-clean-code

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Longest Word in Dictionary 字典中的最长单词的更多相关文章

  1. [leetcode]720. Longest Word in Dictionary字典中最长的单词

    b.compareTo(a) 这个函数是比较两个值得大小,如果b比a大,那么返回1 如果小,那么返回-1,相等返回0 如果比较的是字符串,那么比较字典编纂顺序,b靠前返回-1,靠后返回1 这个题的核心 ...

  2. [LeetCode] Longest Word in Dictionary through Deleting 删除后得到的字典中的最长单词

    Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...

  3. 524. Longest Word in Dictionary through Deleting【Medium】【删除后得到的字典中的最长单词】

    Given a string and a string dictionary, find the longest string in the dictionary that can be formed ...

  4. LeetCode——Longest Word in Dictionary through Deleting

    1. Question Given a string and a string dictionary, find the longest string in the dictionary that c ...

  5. Leetcode720.Longest Word in Dictionary词典中最长的单词

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

  6. FCC JS基础算法题(3):Find the Longest Word in a String (找出最长单词)

    题目描述: 在句子中找出最长的单词,并返回它的长度.函数的返回值应该是一个数字. 基本思路,将字符串转换成数组,然后得出数组中单个元素的长度,对长度进行排序,返回最大的一个 代码: function ...

  7. Longest Word in Dictionary through Deleting - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Longest Word in Dictionary through Deleting - LeetCode 注意点 长度一样的字符串要按字典序返回较小的 ...

  8. 【LeetCode】Longest Word in Dictionary through Deleting 解题报告

    [LeetCode]Longest Word in Dictionary through Deleting 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode. ...

  9. 【Leetcode_easy】720. Longest Word in Dictionary

    problem 720. Longest Word in Dictionary 题意: solution1: BFS; class Solution { public: string longestW ...

随机推荐

  1. Repeating Decimals UVA - 202

    The / repeats indefinitely with no intervening digits. In fact, the decimal expansion of every ratio ...

  2. fetch()函数使用的一些技巧

    最近项目用到了一些es6的知识,其中大篇幅在vue框架中使用了fetch()函数,总结了一些使用的技巧: 一, 1,POST带参数)fetch提交json格式的数据到服务器: //fetch替换vue ...

  3. 使用git将文件上传到Coding

    1,首先在Coding上新建项目. 2,填写项目的相关内容. 3,建立项目后复制下面鼠标所选内容. 4,在自己的电脑中建立文件夹. 5,进入该文件夹后,点击鼠标右键,然后再点Git  Clone. 6 ...

  4. 福州大学W班-助教总结

    开学初对自己的期望 在即将到来的学期前,我希望我可以做到以下几点: 1.多参与同学的课程设计,并提出自己的见解 2.不断提高个人的专业技能,活到老学到老 3.能够及时对同学的博客进行评论,并给出有用的 ...

  5. 数据结构基础——指针及动态内存分配(malloc)

    一.指针 C语言中的指针是一种数据类型,比如说我们用int *a;就定义了一个指针a,它指向一个int类型的数.但是这个指针是未初始化的,所以,一般的,我们都在创建指针时初始化它,以免出错,在还不吃的 ...

  6. EasyUI中Tabs添加远程数据的方法。

    tabs加载远程数据: $(function () { $("#btnquery").click(function () { if (!$("#tcontent" ...

  7. 逆向集录_00_不同程序OEP特征总结

    在分析/逆向 程序时,如果事先知道这类程序的一些特征,那将会是事半功倍的: 分析/逆向 程序,和写程序不同,比喻的话:写程序像在作案,分析/逆向 程序就像是在破案,对破案来讲,重在假想和推理: 特征1 ...

  8. linux的脚本应用for循环答应变量

    #!/bin/bash for var in A B C ; do echo "var is $var" done

  9. 第一次制作和使用图标字体-IcoMoon

    开题:之前就有所耳闻,最近两天第一次运用到图标字体.刚开始嘛,一脸懵逼的状态.成功运用之后就来记录一下使用过程咯! 1. 打开在线生成工具:https://icomoon.io/app/#/selec ...

  10. 可空类型 Nullable<T>

    Nullable<T> 内部实现了显示和隐式转换 显示转换: public static explicit operator T(T? value) { return value.Valu ...