携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
题目描述
原题链接 :
720. 词典中最长的单词 - 力扣(LeetCode) (leetcode-cn.com)
给出一个字符串数组 words
组成的一本英语词典。返回 words
中最长的一个单词,该单词是由 words
词典中其他单词逐步添加一个字母组成。
若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。
示例 1:
输入:words = ["w","wo","wor","worl", "world"]
输出:"world"
解释: 单词"world"可由"w", "wo", "wor", 和 "worl"逐步添加一个字母组成。
示例 2:
输入:words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
输出:"apple"
解释:"apply" 和 "apple" 都能由词典中的单词组成。但是 "apple" 的字典序小于 "apply"
提示:
- 1 <= words.length <= 1000
- 1 <= words[i].length <= 30
- 所有输入的字符串 words[i] 都只包含小写字母。
思路分析
- 首先是要对string给排个序
- 其次寻找单个字母,以及其后的以这个字母开头的一系列string(因为必须从单字母才能开始)
- 对于这一系列词,从单独的字母开始加入set,在加入后续单词时,先查看这个单词的前缀是否在set里,如果在,则将其加入set。(因为如果前缀都不在set里,也不可能组成这个单词了)
- 对于更大值的替换,只有大于当前最大值,才会把答案string替换,这样就算是相同的长度的单词,由于字典序靠前的单词先被记录下来,后面同长度的单词就不会被记录,达到了题目要求。
AC 代码
class Solution {
public:
string longestWord(vector<string>& words) {
//首先是要对string给排个序
//其次寻找单个字母,以及其后的以这个字母开头的一系列string
//对于这一系列词,从单独的字母开始加入set,在加入后续单词时,先查看这个单词的前缀是否在set里,如果在,则将其加入set。
string ans="";
int max_num=0;
sort(words.begin(),words.end());
unordered_set<string>se;
for(int i=0;i<words.size();i++){
while(i<words.size()&&words[i].size()>1){
i++;
}
if(i==words.size())break;
char pre=words[i][0];
int end=i;
while(end<words.size()&&words[end][0]==pre){
end++;
}
end--;
se.clear();
string t="";
se.insert(t+pre);
if(ans==""){
ans=pre;
max_num=1;
}
while(i<=end){
int size=words[i].size();
string self_pre=words[i].substr(0,size-1);
if(se.count(self_pre)){
se.emplace(words[i]);
if(size>max_num){
ans=words[i];
max_num=size;
}
}
i++;
}
i=end;
}
return ans;
}
};
//["a","banana","app","appl","ap","apply","apple","b","ba","ban","bana","banan"]