给出一个字符串数组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”。
暴力搜索法
class Solution {
public:
string longestWord(vector<string>& words) {
string ans="";
unordered_set<string> se;
for(string s:words)
se.insert(s);
for(string s:words)
{
if(s.size()>ans.size()||(s.size()==ans.size()&&s.compare(ans)<0))
{
bool f=true;
for(int k=1;k<=s.size();k++) //判断前缀
{
if(!se.count(s.substr(0,k)))
{
f=false;
break;
}
}
if(f)
ans=s;
}
}
return ans;
}
};
暴力法(排序)
class Solution {
public:
static bool cmp(string s1, string s2)
{
if (s1.size() != s2.size())
return s1.size() > s2.size(); //长度长的字符排在前面
// compare说明
// 两个字符串相同,返回0。
// 调用字符串小与被调用字符串,返回 - 1。
// 调用字符串大于被调用字符串,返回1。
else
//return s1.compare(s2)==-1 ? true:false;
return s1<s2;
}
string longestWord(vector<string>& words) {
unordered_set<string> se;
for(string s:words)
se.insert(s);
sort(words.begin(),words.end(),cmp);
for(string s:words)
{
cout<<s<<endl;
}
for(string s:words)
{
bool f=true;
for(int k=1;k<s.size();++k)
{
if(!se.count(s.substr(0,k)))
{
f=false;
break;
}
}
if(f)
return s;
}
return "";
}
};
字典树(Trie 树)
class Solution {
public:
class tree{
public:
bool word_here;
vector<tree*> v;
tree():word_here(false),v(26){}
static void insert(tree* t,string& str)
{
for(char c:str)
{
if(!t->v[c-'a'])
t->v[c-'a']= new tree();
t=t->v[c-'a'];
}
t->word_here=true;
}
static bool search(tree* t,string& str)
{
for(char c: str)
{
if(!t->v[c-'a']->word_here)
return false;
t=t->v[c-'a'];
}
return true;
}
};
string longestWord(vector<string>& words) {
tree* root=new tree();
for(string& s:words)
tree::insert(root,s);
string ans="";
for(string& s:words)
{
if(s.size()>ans.size()&&tree::search(root,s))
ans=s;
else if(s.size()==ans.size()&& s<ans &&tree::search(root,s))
ans=s;
}
return ans;
}
};
排序后字典树
负优化,效率慢很多
class Solution {
public:
class tree{
public:
bool word_here;
vector<tree*> v;
tree():word_here(false),v(26){}
static void insert(tree* t,string& str,string& ans)
{
cout<<"输入"<<str<<endl;
if(!search(t,str))
return;
if(str.size()>ans.size())
ans=str;
else if(str.size()==ans.size()&&str<ans)
ans=str;
if(str.size()==1)
return;
cout<<"ans输出"<<str<<endl;
for(char c:str)
{
if(!t->v[c-'a'])
t->v[c-'a']= new tree();
t=t->v[c-'a'];
}
t->word_here=true;
}
static bool search(tree* t,string& str)
{
for(int i=0;i<str.size()-1;++i)
{
char c=str[i];
if(!t->v[c-'a']||!t->v[c-'a']->word_here)
return false;
t=t->v[c-'a'];
}
return true;
}
static void init(tree* t,char& c)
{
if(!t->v[c-'a'])
t->v[c-'a']= new tree();
t->v[c-'a']->word_here=true;
}
};
static bool cmp(string s1, string s2)
{
return s1.size() < s2.size(); //长度小的字符排在前面
}
string longestWord(vector<string>& words) {
string ans="";
tree* root=new tree();
sort(words.begin(),words.end(),cmp);
for(string& s:words)
{
if(s.size()==1)
tree::init(root,s[0]);
}
for(string& s:words)
tree::insert(root,s,ans);
cout<<"return ans="<<ans<<endl;
return ans;
}
};