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. python读取txt、csv、xml

    读取txt,无需引入任何包: user_file = open('user_info.txt','r') lines = user_file.readlines() user_file.close() ...

  2. easyui控件写法造成的错误

    <input id="driver" name="driver" class="easyui-combobox" data-optio ...

  3. 关于hadoop集群下Datanode和Namenode无法访问的解决方案

    HDFS架构 HDFS也是按照Master和Slave的结构,分namenode,secondarynamenode,datanode这几个角色. Namenode:是maseter节点,是大领导.管 ...

  4. C语言--嵌套循环

    一.PTA实验作业 题目1 水果价格 1.本题PTA提交列表 2.设计思路 第一步:定义变量number,表示输入的编号 第二步:定义变量i,用来记录编号数目 第三步:输出菜单:[1] apple [ ...

  5. Alpha阶段小结

    1 团队的源码仓库地址 https://github.com/WHUSE2017/MyGod 2 Alpha过程回顾 2.1 团队项目预期 有一个可视化的安卓APP,实现二手交易基本功能.预期的典型用 ...

  6. Packet for query is too large (84 > -1).

    windows下的resin配置连接mysql,常用的安全的做法是将数据库信息配置到conf目录下的resin.xml文件中. 因为resin连接mysql不是必须的,所以resin本身没有提供mys ...

  7. DELL EqualLogic PS存储硬盘故障数据恢复成功案例分享

    DELL EqualLogic PS4000采用虚拟ISCSI SAN阵列,为远程或分支办公室.部门和中小企业存储部署带来企业级功能.智能化.自动化和可靠性.以简化的管理.快速的部署及合理的价格满足了 ...

  8. 织梦cms网上复制图片不可用的解决方法

    背景描述: 织梦cms采集图片集时, 需要使用织梦cms提供的"网上复制图片"的功能, 好像我这里这个功能一直不可用, 今天下定决心研究了下源代码并进行了适当修改, 将我的修改提供 ...

  9. linux cenots7安装mysql

        1.下载mysql 下载的话先确认好版本. system:centos7 mysql:5.7 下面的版本自己选择,一般是86位的. 下载好的文件 2.上传到服务器 soft文件夹,终端也进入了 ...

  10. Python之旅.第三章.函数3.28

    一.命名关键字参数: 什么是命名关键字参数?格式:在*后面参数都是命名关键字参数特点:1 必须被传值1 约束函数的调用者必须按照key=value的形式传值2 约束函数的调用者必须用我们指定的key名 ...