现在的位置: 首页 > 综合 > 正文

Word Ladder II

2018年04月01日 ⁄ 综合 ⁄ 共 5648字 ⁄ 字号 评论关闭

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
思路:这是一道BFS的题。保存所有的最短的路径,以下我的解法大数据时超出内存。
class Solution {
public:
    bool isLadder(string a, string b) {
        int co = 0;
        int i;
        for (i=0; i<a.size(); ++i) {
            if (a[i] != b[i]) {
                co++;
            }
        }
        if (co>1) {
            return false;
        }
        return true;
    }
    
    struct Data {
    <span style="white-space:pre">	</span>string str;
    <span style="white-space:pre">	</span>stack<string> strSeq;
    <span style="white-space:pre">	</span>Data(string a):str(a) {
    <span style="white-space:pre">		</span>strSeq.push(a);
    <span style="white-space:pre">	</span>}
    };
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
        vector<vector<string> > res;
        vector<string> per;
        if (isLadder(start, end)) {
            per.push_back(start);
            per.push_back(end);
            res.push_back(per);
            return res;
        }
        unordered_set<string> myDict = dict;
        Data dEnd(end);
        queue<Data> pre, back;
        back.push(dEnd);
        int i,j;
        
        while (!back.empty()) {
        <span style="white-space:pre">	</span>while (!pre.empty()) {
        <span style="white-space:pre">		</span>pre.pop();
        <span style="white-space:pre">	</span>}
        <span style="white-space:pre">	</span>bool flag = false;
        <span style="white-space:pre">	</span>while (!back.empty()) {
        <span style="white-space:pre">		</span>Data top = back.front();
        <span style="white-space:pre">		</span>back.pop();
        <span style="white-space:pre">		</span>for (i=0; i<top.str.size(); ++i) {
        <span style="white-space:pre">			</span>for (j=0; j<26; ++j) {
        <span style="white-space:pre">				</span>string tmp = top.str;
        <span style="white-space:pre">				</span>tmp[i] = 'a' + j;
        <span style="white-space:pre">				</span>if ((tmp!=top.str) && (myDict.find(tmp)!=myDict.end())) {
        <span style="white-space:pre">					</span>Data dTmp(tmp);
        <span style="white-space:pre">					</span>dTmp.strSeq = top.strSeq;
        <span style="white-space:pre">					</span>dTmp.strSeq.push(tmp);
        <span style="white-space:pre">					</span>pre.push(dTmp);
        <span style="white-space:pre">					</span>if (isLadder(tmp, start)) {
        <span style="white-space:pre">						</span>flag = true;
        <span style="white-space:pre">					</span>}
        <span style="white-space:pre">				</span>}
        <span style="white-space:pre">			</span>}
        <span style="white-space:pre">		</span>}
        <span style="white-space:pre">	</span>}
        <span style="white-space:pre">	</span>back = pre;
        <span style="white-space:pre">	</span>if (flag) {
        <span style="white-space:pre">		</span>break;
        <span style="white-space:pre">	</span>}
        }
        while (!back.empty()) {
        <span style="white-space:pre">	</span>Data top = back.front();
        <span style="white-space:pre">	</span>back.pop();
    <span style="white-space:pre">		</span>vector<string> vStr;
    <span style="white-space:pre">		</span>unordered_set<string> sStr;
    <span style="white-space:pre">		</span>vStr.push_back(start);
    <span style="white-space:pre">		</span>string cmp = "";
    <span style="white-space:pre">		</span>while (!top.strSeq.empty()) {
    <span style="white-space:pre">			</span>cmp = top.strSeq.top();
    <span style="white-space:pre">			</span>top.strSeq.pop();
    <span style="white-space:pre">			</span>vStr.push_back(cmp);
    <span style="white-space:pre">			</span>if (sStr.find(cmp) != sStr.end()) {
    <span style="white-space:pre">				</span>break;
    <span style="white-space:pre">			</span>}
    <span style="white-space:pre">			</span>sStr.insert(cmp);
    <span style="white-space:pre">		</span>}
    <span style="white-space:pre">		</span>if ((sStr.size() == vStr.size()-1) && isLadder(cmp, start)) {
    <span style="white-space:pre">			</span>res.push_back(vStr);
        <span style="white-space:pre">	</span>}
        }
        /*for (i=0; i<res.size(); ++i) {
        <span style="white-space:pre">	</span>for (j=0; j<res[i].size(); ++j) {
        <span style="white-space:pre">		</span>cout << res[i][j] << " ";
        <span style="white-space:pre">	</span>}
        <span style="white-space:pre">	</span>cout << endl;
        }*/
        return res;
    }
};

以上的解法超出了空间限制。改进:可以设一个path,key为当前单词,value表示当前单词的后驱单词。再分别设置变量curStep和nextStep,表示层序变量的上一层和下一层。为了防止字典中的单词多次使用,每比较完一层需要将字典中该层出现过的单词过滤掉。因此代码如下:(代码思路参考了网上的资料)

class Solution {
public:
    vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) {
        map<string,vector<string> > path;
 
        unordered_set<string>rightside=dict;
 
        rightside.erase(start);
        
        unordered_set<string>curStep;
        unordered_set<string>nextStep;
        curStep.insert(start);
        while(curStep.find(end)==curStep.end()&&!rightside.empty())
        {
            for(auto iter_us_cur=curStep.begin();iter_us_cur!=curStep.end();++iter_us_cur)
            {
                string temp;
                for(int i=0;i<(*iter_us_cur).length();++i)
                {
                    for(int j = 0;j<26;j++)
                    {
                        temp = *iter_us_cur;
                        if(temp[i]!=('a'+j))
                        {
                            temp[i] = ('a'+j);
                        }
                        
                        if(rightside.find(temp) != rightside.end())
                        {
                            nextStep.insert(temp);
                            if(path.find(*iter_us_cur)==path.end())
                            {
                                vector<string> V;
                                path.insert(make_pair(*iter_us_cur,V));
                            }
                            
                            path[*iter_us_cur].push_back(temp);
                        }
                    }                    
                }
            }
            
            if(nextStep.empty())break;
            for(auto iter_set=nextStep.begin();iter_set!=nextStep.end();++iter_set)
            {
                rightside.erase(*iter_set);
            }
            curStep = nextStep;
            nextStep.clear();
        }
        
        vector<vector<string> > result;
        vector<string> temp;
        
        if(curStep.find(end)!=curStep.end())
        {
            output(path,start,end,result,temp);
        }
 
        return result;
 
    }
    
    void output(map<string,vector<string> >&path,string start,string end,vector<vector<string> >&result,vector<string> & temp)
    {
        temp.push_back(start);
 
        if(start==end)
        {
            result.push_back(temp);return;
        }
 
        vector<string>::iterator iter_v;
        
        for(iter_v=path[start].begin();iter_v!=path[start].end();++iter_v)
        {
            output(path,*iter_v,end,result,temp);temp.pop_back();
        }
    }
};

抱歉!评论已关闭.