LeetCode127:Word Ladder II

题目:

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

  • Only one letter can be changed at a time
  • 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.
  • 解题思路:

  • 这道题可真是耗费我老多时间,提交结果要不就是超时,要不就是内存限制,哎,编程能力急待提高啊。
  • 本题是Word Ladder的升级版,可对我这菜鸟才说升的可不止一级。该题主要的解题思路就是BFS+DFS。首先如Word Ladder,构造抽象图,然后利用BFS找到从start到end的最短路径,但寻找最短路径的过程中,我们需要保持最短路径最个节点的父节点信息,以便之后进行所有最短路径结果的重构,重构路径采用的DFS回溯,从end节点开始一直到start节点。好了,不多说了,直接上代码。
  • 实现代码:(注:该代码未能AC,出现内存限制,忘牛人指正,实在不知错在哪里)
  • #include <iostream>
    
    #include <string>
    
    #include <vector>
    
    #include <queue>
    
    #include <unordered_set>
    
    #include <unordered_map>
    
    #include <algorithm>
    
    using namespace std;
    
    
    
    /**
    
    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
    
    
    
    Only one letter can be changed at a time
    
    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.
    
    */
    
    
    
    class Solution {
    
    public:
    
        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
    
            vector<vector<string>> resvec;
    
            if(start.empty() || end.empty() || dict.empty())
    
                return resvec;
    
            unordered_map<string, vector<string>> premap;
    
            //这里需要用到两个vector来模拟两个队列而不是直接用两个队列,是因为需要对队列进行遍历,queue做不到 
    
            vector<string> squ[2]; 
    
            squ[0].push_back(start);
    
            bool qid = false;
    
            bool finish = false;
    
            while(!squ[qid].empty())
    
            {
    
                squ[!qid].clear();
    
                vector<string>::iterator iter;
    
                for(iter = squ[qid].begin(); iter != squ[qid].end(); ++iter)
    
                    dict.erase(*iter);//从dict中删除同一层的所有节点,以免造成循环操作 
    
                for(iter = squ[qid].begin(); iter != squ[qid].end(); ++iter)//处理同一层节点 
    
                {
    
                    string curstr = *iter;                
    
                    for(int i = 0; i < curstr.size(); i++)
    
                    {
    
                        char t = curstr[i];
    
                        for(char j = 'a'; j <= 'z'; j++)
    
                        {
    
                            if(j == curstr[i])
    
                                continue;
    
                            curstr[i] = j;
    
                            if(curstr == end)
    
                            {
    
                                finish = true;
    
                                premap[curstr].push_back(*iter);
    
                                
    
                            }                            
    
                            else if(dict.count(curstr) > 0)
    
                            {
    
                                squ[!qid].push_back(curstr);
    
                                premap[curstr].push_back(*iter);
    
                            }
    
                        }
    
                        curstr[i] = t;
    
                        
    
                    }                                            
    
                }
    
                if(finish)//说明已经处理到了end节点,可以直接break循环,进行结果重构了 
    
                        break;            
    
                qid = !qid;//表示将要处理的下一层 
    
            }
    
            if(premap.count(end) == 0)//表明end节点的父节点不存在,所有没有到end的转换,直接返回空resvec 
    
                return resvec;
    
            vector<string> tmp;
    
            getResult(resvec, tmp, premap, start, end);
    
            return resvec;        
    
        }
    
        
    
    
    
        
    
        //DFS 
    
        void getResult(vector<vector<string> > &resvec, vector<string> &tmp,   
    
            unordered_map<string, vector<string> > &premap, string &start, string &cur)  
    
        {  
    
            tmp.push_back(cur);
    
            if (cur == start)  
    
            {  
    
                resvec.push_back(tmp);  
    
                reverse(resvec.back().begin(), resvec.back().end());    
    
            }
    
            else
    
            {
    
                vector<string> v = premap[cur];  
    
                for (int i = 0; i < v.size(); i++)  
    
                {   
    
                    getResult(resvec, tmp, premap, start, v[i]);  
    
                }            
    
            }  
    
            tmp.pop_back();  
    
        }
    
    };
    
    
    
    
    
    int main(void)
    
    {
    
        string start("hit");
    
        string end("cog");
    
        string strarr[] = {"hot","dot","dog","lot","log"};
    
        int n = sizeof(strarr) / sizeof(strarr[0]);
    
        unordered_set<string> dict(strarr, strarr+n);
    
        Solution solution;
    
        vector<vector<string>> resvec = solution.findLadders(start, end, dict);
    
        vector<vector<string>>::iterator iter;
    
        for(iter = resvec.begin(); iter != resvec.end(); ++iter)
    
        {
    
            vector<string> tmp = *iter;
    
            vector<string>::iterator it;
    
            for(it = tmp.begin(); it != tmp.end(); ++it)
    
                cout<<*it<<" ";
    
            cout<<endl;
    
        }
    
        return 0;
    
    }

    以下附网上大神AC代码一份:

    class Solution {
    
    public:
    
        vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict)
    
        {
    
            result_.clear();
    
            unordered_map<string, vector<string>> prevMap;
    
            for(auto iter = dict.begin(); iter != dict.end(); ++iter)
    
                prevMap[*iter] = vector<string>();
    
            vector<unordered_set<string>> candidates(2);
    
            int current = 0;
    
            int previous = 1;
    
            candidates[current].insert(start);
    
            while(true)
    
            {
    
                current = !current;
    
                previous = !previous;
    
                for (auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
    
                    dict.erase(*iter);
    
                candidates[current].clear();
    
                
    
                for(auto iter = candidates[previous].begin(); iter != candidates[previous].end(); ++iter)
    
                {
    
                    for(size_t pos = 0; pos < iter->size(); ++pos)
    
                    {
    
                        string word = *iter;
    
                        for(int i = 'a'; i <= 'z'; ++i)
    
                        {
    
                            if(word[pos] == i)continue;
    
                            word[pos] = i;
    
                            if(dict.count(word) > 0)
    
                            {
    
                                prevMap[word].push_back(*iter);
    
                                candidates[current].insert(word);
    
                            }
    
                        }
    
                    }
    
                }
    
                if (candidates[current].size() == 0)
    
                    return result_;
    
                if (candidates[current].count(end)) break;
    
            }
    
            vector<string> path;
    
            GeneratePath(prevMap, path, end);
    
            return result_;
    
        }
    
        
    
    private:
    
        void GeneratePath(unordered_map<string, vector<string>> &prevMap, vector<string>& path, const string& word)
    
        {
    
            if (prevMap[word].size() == 0)
    
            {
    
                path.push_back(word);
    
                vector<string> curPath = path;
    
                reverse(curPath.begin(), curPath.end());
    
                result_.push_back(curPath);
    
                path.pop_back();
    
                return;
    
            }
    
            path.push_back(word);
    
            for (auto iter = prevMap[word].begin(); iter != prevMap[word].end(); ++iter)
    
                GeneratePath(prevMap, path, *iter);
    
            path.pop_back();
    
        }
    
        vector<vector<string>> result_;
    
    };
    代码来源: http://blog.csdn.net/doc_sgl/article/details/13341405

    你可能感兴趣的:(LeetCode)