word ladder 2 的复杂实现

来源:互联网 发布:淘宝会员名可以修改了 编辑:程序博客网 时间:2024/05/22 13:05

采用分治法的思想。

(1)把所有两数之和计算出来,并保存在multimap中。放在unordered_multimap中的效率更高,但是因为其采用hash定位元素的方法,导致map中的数据不能按序索引。故要放弃unordered,虽然在有的版本中unordered的某些类型可以保持一定顺序,但本质是无序的。

(2)对关联容器进行删除操作后,迭代器就会失效。这个一定要注意。例如:auto p = mmp.equal_range(val) ,此时如果对p.first和p.second之内的迭代器进行删除,那么下次的p就要重新计算。

(3)此题可用trie树加以优化,后话。

<span style="font-size:14px;">vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {        vector<vector<string>> res;  vector<string> path;        if(!dict.size()) return res;                  queue<string> q; int minLen=10000;int len;string ss;        unordered_map<string,int> mp; unordered_multimap<string,string> parent;        dict.insert(end);        if(dict.count(start)) dict.erase(start); q.push(start); mp[start]=1;        parent.insert(make_pair(start,""));        while(!q.empty()){            auto str = q.front(); q.pop();            for(auto i=0 ; i< str.size(); ++i){                auto tmp=str;                //auto p= parent.equal_range(str);  <strong>//if we put p here ,then will get RE, because p are invalid after erase operation!!</strong>                for(char j='a';j<='z';++j){                    tmp[i]=j; //bool f=false;//cout<<tmp<<endl;                    /*auto p= parent.equal_range(str); <strong>// update p everytime an erase ocur</strong>                    for(auto t=p.first;t!=p.second;++t)                    if(t->second==tmp) f=true;                    if(f) break;*/                                         if ( str[i]!=j && dict.count(tmp)  ) {                        if(tmp==end){                             len = mp[str]+1;                            minLen = min(len,minLen);                            if(len>minLen) continue;                            if(len==minLen){                                path.clear();                                 ss=str;                                path.push_back(end);                                while(ss!="") {                                path.push_back(ss);                                auto it=parent.find(ss);<span style="white-space:pre"></span><strong>//change it to multimap, ok but low efficient</strong>                                auto cnt=parent.count(ss);                                ss=it->second;                                if(cnt>1) parent.erase(it); <strong>// wrong! elements in this is unordered, you should reley on this</strong>                                }                                res.push_back(path);                            }                         }                         else{                                                        if(mp[str]+1<minLen) {                            if(parent.find(tmp)!=parent.end() && mp[str]+1 != mp[tmp] ) continue;                            mp[tmp]=mp[str]+1;                            q.push(tmp);                            parent.insert(make_pair(tmp,str));                            }                        }                    }                 }            }        }cout<<res.size()<<endl;        for(auto &vec:res)        reverse(vec.begin(),vec.end());        return res;    }</span>

如果改成multimap效率就会大打折扣,但是寻找父亲节点必须依赖循序性。如果想用unordered,唯一的办法是在此过程不用map,办法是有的:represent paths as string。如下:

vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {        vector<vector<string>> res;         if(!dict.size()) return res;                int minLen=10000,len;string ss,road,tmpRoad;        vector<string> paths,vtmp;        queue<string> q,path;        unordered_map<string,int> mp;        unordered_map<string,string> parent;                dict.insert(end);dict.erase(start); q.push(start); mp[start]=1;         path.push(start);parent.insert(make_pair(start,""));                while(!q.empty()){            auto str(q.front()); q.pop();//cout<<"*" << str;            <strong>auto road(path.front());path.pop();</strong>//cout<<road<<endl;            for(auto i=0 ; i< str.size(); ++i){                auto tmp(str);                 for(char j='a';j<='z';++j){                    tmp[i]=j; tmpRoad= road;                    if ( str[i]!=j && dict.find(tmp)!=dict.end() ) {  //cout<<tmp<<endl;                        if(tmp==end){                            len = mp[str]+1;//cout<<str<<endl;cout<<len<<endl;                            minLen = min(len,minLen);//cout<<minLen<<endl;                            if(len>minLen) continue;                            if(len==minLen){                                <strong>tmpRoad +=end;                                paths.push_back(tmpRoad);</strong>                            }                         }                         else{                                                        if(mp[str]+1<minLen) {                            if(parent.find(tmp)!=parent.end() && mp[str]+1 != mp[tmp] ) continue;                            mp[tmp]=mp[str]+1;//cout<<"["<< tmp<<"]";                            q.push(tmp);                            <strong>tmpRoad +=tmp;                            path.push(tmpRoad);</strong>                            parent.insert(make_pair(tmp,str));                            }                        }                    }                 }            }        }//cout<<res.size()<<endl;        //for(auto p:paths)        //cout<<p<<endl;        for(auto &p:paths){        vtmp.clear();        for(int i=0 ; i<p.size()-2;i=i+3)        vtmp.push_back(p.substr(i,3));        res.push_back(vtmp);        }        return res;    }
虽然如此,效率还是不行,如何改进且待下回分解。



0 0