2014-04-29 04:22
题目:给定一堆长度都相等的单词,和起点、终点两个单词,请从这堆单词中寻找一条变换路径,把起点词变成终点词,要求每次变换只能改一个字母。
解法:Leetcode中有Word Ladder,这题基本思路一致。
代码:
1 // 18.10 Given a list of words, all of same length. Given a source and a destionation words, you have to check if there exists a path between the two. Every time you may change only one letter in the word. 2 // This is my code from leetcode problem set: word ladder 3 #include <string> 4 #include <unordered_map> 5 #include <unordered_set> 6 #include <vector> 7 using namespace std; 8 9 class Solution { 10 public: 11 vector<vector<string> > findLadders(string start, string end, unordered_set<string> &dict) { 12 unordered_map<string, vector<string> > back_trace; 13 vector<unordered_set<string> > level(2); 14 15 dict.insert(start); 16 dict.insert(end); 17 18 int flag, nflag; 19 flag = 0; 20 nflag = !flag; 21 level[flag].insert(start); 22 23 unordered_set<string>::iterator usit; 24 char ch, old_ch; 25 string word; 26 while (true) { 27 flag = !flag; 28 nflag = !nflag; 29 level[flag].clear(); 30 for (usit = level[nflag].begin(); usit != level[nflag].end(); ++usit) { 31 dict.erase(*usit); 32 } 33 for (usit = level[nflag].begin(); usit != level[nflag].end(); ++usit) { 34 word = *usit; 35 for (size_t i = 0; i < word.size(); ++i) { 36 old_ch = word[i]; 37 for (ch = 'a'; ch <= 'z'; ++ch) { 38 if (ch == old_ch) { 39 continue; 40 } 41 word[i] = ch; 42 if (dict.find(word) != dict.end()) { 43 back_trace[word].push_back(*usit); 44 level[flag].insert(word); 45 } 46 } 47 word[i] = old_ch; 48 } 49 } 50 if (level[flag].empty() || level[flag].count(end) > 0) { 51 // found or not found 52 break; 53 } 54 } 55 56 single_result.clear(); 57 for (size_t i = 0; i < result.size(); ++i) { 58 result[i].clear(); 59 } 60 result.clear(); 61 62 if (!back_trace.empty()) { 63 recorverPath(back_trace, end); 64 } 65 66 return result; 67 } 68 private: 69 vector<vector<string> > result; 70 vector<string> single_result; 71 72 void recorverPath(unordered_map<string, vector<string> > &back_trace, string cur) { 73 if (back_trace.count(cur) == 0) { 74 // this word has no back trace, it is unreachable. 75 vector<string> single_path(single_result); 76 77 single_path.push_back(cur); 78 reverse(single_path.begin(), single_path.end()); 79 result.push_back(single_path); 80 return; 81 } 82 83 const vector<string> &v = back_trace[cur]; 84 vector<string>::const_iterator usit; 85 86 single_result.push_back(cur); 87 for (usit = v.begin(); usit != v.end(); ++usit) { 88 recorverPath(back_trace, *usit); 89 } 90 single_result.pop_back(); 91 } 92 };