Question :


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.


For Example:

Graph Array =

[


h i t

h o t

d o t

d o g

l o t

l o g


c o g

]


Anwser 1 :

class Solution {
public:
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (dict.find(start) == dict.end()) {
            dict.insert(start);
        }
        if (dict.find(end) == dict.end()) {
            dict.insert(end);
        }
        
        queue<string> q;
        unordered_map<string, pair<int, vector<string> > > dep_map;
        dep_map[start] = pair<int, vector<string> >(1, vector<string>());
        q.push(start);
        
        int depth = 1;
        int len = start.length();           // word length
        int min_depth = dict.size() + 2;    // 2 for start and end words
        while (!q.empty() && min_depth > depth) {
            string cur = q.front();
            q.pop();
            
            depth = dep_map[cur].first;
            for (int i=0; i<len; ++i)       // check word(s)
            {
                string adj = cur;
                for (char a='a'; a<='z'; ++a) {
                    if (a==cur[i]) continue;
                    
                    adj[i] = a;
                    if (adj == end) {
                        min_depth = depth+1;
                    }
                    
                    if (dict.find(adj) != dict.end()) 
                    {
                        unordered_map<string, pair<int, vector<string> > > ::iterator it = dep_map.find(adj);
                        if(it == dep_map.end()) {
                            pair<int, vector<string> > value(depth + 1, vector<string>());
                            value.second.push_back(cur);
                            dep_map[adj] = value;
                            q.push(adj);
                        } else if ((it->second).first == depth+1) {
                            it->second.second.push_back(cur);
                        }
                    }
                }       
            }
        }   // end while
        
        vector<vector<string> > result;
        if (min_depth == dict.size() + 2) {     // only for start and end words
            return result;
        }
        
        vector<string> stack;
        vector<string> sequence;
        stack.push_back(end);
        while(!stack.empty()) {
            string top = stack.back();
            stack.pop_back();
            sequence.push_back(top);
            vector<string> &sons = dep_map[top].second;
            for(int i=0; i<sons.size(); ++i) {
                stack.push_back(sons[i]);
            }
            
            if (sons.size()==0) {
                int index = result.size();
                result.push_back(vector<string>());
                for (int i=sequence.size()-1; i>=0; --i) {
                    result[index].push_back(sequence[i]);   // save result
                }
                top = sequence.back();
                sequence.pop_back();
                while(!sequence.empty()) 
                {
                    string father = sequence.back();
                    vector<string> brothers = dep_map[father].second;
                    if (top != brothers[0]) {
                        break;
                    }
                    sequence.pop_back();
                    top = father;
                }
            }
        }
        return result;
    }
};


Anwser 2 :

class Solution {
public:
    struct Node {
        vector<string> parent;
        int layer;
    };
    
    void buildResult( vector<vector<string>> &result, list<string> &r, string start, string end, unordered_map<string, Node> &checkmap)
    {
        r.push_front(end);
        if(end==start) {
            vector<string> oneresult(r.begin(), r.end());
            result.push_back(oneresult);
        } else {
            for(const string &s:checkmap[end].parent) {
                buildResult(result, r, start, s, checkmap);
            }
        }

        r.pop_front();
    }

    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        unordered_map<string, Node> checkmap;
        list<string> layer;
        checkmap[start].layer = 1;
        checkmap[start].parent.push_back(start);
        layer.push_back(start);

        vector<vector<string>> result;

        bool hasfind = false;
        string layerend = start;
        string last;
        while(!layer.empty())
        {
            string s = layer.front();
            layer.pop_front();
            int currentlayer = checkmap[s].layer;
            int L = s.size();
            for(int i = 0; i< L; i++)
            {
                string temp = s;
                for(int j = 0; j < 26; j++)
                {
                    temp[i] = j+'a';
                    if(temp==end) {
                        checkmap[temp].parent.push_back(s);
                        checkmap[temp].layer = checkmap[s].layer+1;

                        hasfind = true;
                    } else if(dict.count(temp)&&s!=temp) {
                        if(checkmap.count(temp)==0){
                            checkmap[temp].parent.push_back(s);
                            checkmap[temp].layer = checkmap[s].layer+1;
                            layer.push_back(temp);
                            last = temp;
                        } else if(checkmap[s].layer<checkmap[temp].layer) {
                            checkmap[temp].parent.push_back(s);   
                        }
                    }

                }
            }   // end for 

            if(s == layerend) 
            {
                layerend = last;
                if(hasfind) {
                    list<string> r;
                    buildResult(result, r, start, end, checkmap);
                    break;
                }
            }
            
        }   // end while 

        return result;
    }
};



参考推荐:


Word Ladder II


stack