Word Ladder Problem (DFS + BFS)

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

 

UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

Code:

  1 class Solution {
  2 public:
  3     vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
  4         //1.convert vector to unordered_set
  5         unordered_set<string> wordDict;
  6         for(int i=0; i<wordList.size(); i++)
  7         {
  8             wordDict.insert(wordList[i]);
  9         }
 10         if(wordDict.find(endWord) == wordDict.end()) return vector<vector<string>>();
 11         
 12         //2.record each node's pre_node from begin to end using bfs strategy
 13         unordered_map<string, vector<string>> preNode;
 14         bfs(preNode, wordDict, beginWord, endWord);
 15         
 16         //3.search all the road using dfs from end to start
 17         vector<vector<string>> res;
 18         vector<string> temp;
 19         dfs(beginWord, endWord, temp, preNode, res);
 20         
 21         return res;
 22     }
 23     
 24 private:
 25     void bfs(unordered_map<string, vector<string>>&preNode, 
 26              unordered_set<string>& wordDict, string beginWord, string endWord)
 27     {
 28         queue<string> q;
 29         unordered_set<string> visit;
 30         visit.insert(beginWord);
 31         vector<string> connect;
 32         q.push(beginWord);
 33         while(!q.empty())
 34         {
 35             int len = q.size();
 36             vector<string> tmpVisit;
 37             while(len--)
 38             {
 39                 string current = q.front();
 40                 q.pop();
 41                 isConnect(connect, wordDict, current, endWord, visit);
 42                 for(int i=0; i<connect.size(); i++)
 43                 {
 44                     if(visit.find(connect[i]) == visit.end()) // not visited
 45                     {
 46                         if(preNode[connect[i]].empty())
 47                         {
 48                             tmpVisit.push_back(connect[i]);
 49                             q.push(connect[i]);
 50                         }
 51                         preNode[connect[i]].push_back(current);
 52                     }
 53                 }
 54             } //each level
 55             for(int j=0; j<tmpVisit.size(); j++)
 56             {
 57                 visit.insert(tmpVisit[j]);
 58             }
 59             if(visit.find(endWord) != visit.end())
 60                 return;
 61         }
 62     }
 63     
 64     void isConnect(vector<string>& connect, unordered_set<string>& wordDict,
 65                   const string& current, const string& end, unordered_set<string>& visit)
 66     {
 67         connect.clear();
 68         string cur = current;
 69         for(int i=0; i<cur.size(); i++)
 70         {
 71             char t = cur[i];
 72             for(char c='a'; c<'z'; c++)
 73             {
 74                 if(c == t) continue;
 75                 cur[i] = c;
 76                 if((wordDict.find(cur) != wordDict.end()) && visit.find(cur) == visit.end())
 77                 {
 78                     connect.push_back(cur);
 79                 }
 80             }
 81             cur[i] = t;
 82         }
 83     }
 84     
 85     void dfs(const string& beginWord, const string& t, vector<string> tmp, 
 86             unordered_map<string, vector<string>>& preNode, vector<vector<string>>& res)
 87     {
 88         if(t == beginWord)
 89         {
 90             tmp.push_back(beginWord);
 91             vector<string> tmpres(tmp.rbegin(), tmp.rend());
 92             res.push_back(tmpres);
 93             return;
 94         }
 95         tmp.push_back(t);
 96         for(int i=0; i<preNode[t].size(); i++)
 97         {
 98             dfs(beginWord, preNode[t][i], tmp, preNode, res);
 99         }
100     }
101 };
View Code

 

posted @ 2017-10-20 21:22  kossle  阅读(184)  评论(0编辑  收藏  举报