C++ LeetCode 720 词典中最长的单词(前缀树--Trie树)

给出一个字符串数组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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值