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:
- Only one letter can be changed at a time.
- 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:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 };