[LeetCode] Word Ladder II

This is a tough problem! I read some solutions from the web. This link provides a one-end BFS solution. The code is reorganized as follows.

 1 class Solution {
 2 public:
 3     vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
 4         dict.insert(end);
 5         unordered_set<string> current;
 6         unordered_set<string> next;
 7         current.insert(start);
 8         ladder.push_back(end);
 9         while (true) {
10             for (string cur : current)
11                 dict.erase(cur);
12             for (string cur : current)
13                 findChildren(cur, next, dict);
14             if (next.empty()) return ladders;
15             if (next.find(end) != next.end()) {
16                 genLadders(start, end);
17                 return ladders;
18             }
19             current.clear();
20             swap(current, next);
21         }
22     }
23 private:
24     unordered_map<string, vector<string> > ancestors;
25     vector<string> ladder;
26     vector<vector<string> > ladders;
27     
28     void findChildren(string& word, unordered_set<string>& next, unordered_set<string>& dict) {
29         int len = word.length();
30         string ancestor = word;
31         for (int p = 0; p < len; p++) {
32             char letter = word[p];
33             for (int i = 0; i < 26; i++) {
34                 word[p] = 'a' + i;
35                 if (dict.find(word) != dict.end()) {
36                     next.insert(word);
37                     ancestors[word].push_back(ancestor);
38                 }
39             }
40             word[p] = letter;
41         }
42     }
43     
44     void genLadders(string& start, string& end) {
45         if (start == end) {
46             reverse(ladder.begin(), ladder.end());
47             ladders.push_back(ladder);
48             reverse(ladder.begin(), ladder.end());
49             return;
50         }
51         for (string ancestor : ancestors[end]) {
52             ladder.push_back(ancestor);
53             genLadders(start, ancestor);
54             ladder.pop_back();
55         }
56     }
57 };

This link shares a two-end BFS solution, which is much faster! I have also rewritten that code below. 

 1 class Solution {
 2 public:
 3     vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
 4         vector<string> ladder;
 5         vector<vector<string> > ladders;
 6         ladder.push_back(start);
 7         unordered_set<string> startWords;
 8         unordered_set<string> endWords;
 9         startWords.insert(start);
10         endWords.insert(end);
11         unordered_map<string, vector<string> > children;
12         bool flip = true;
13         if (searchLadders(startWords, endWords, children, dict, ladder, ladders, flip))
14             genLadders(start, end, children, ladder, ladders);
15         return ladders;
16     }
17 private:
18     bool searchLadders(unordered_set<string>& startWords, unordered_set<string>& endWords,
19                        unordered_map<string, vector<string> >& children, unordered_set<string>& dict,
20                        vector<string>& ladder, vector<vector<string> >& ladders, bool& flip) {
21         flip = !flip;
22         if (startWords.empty()) return false;
23         if (startWords.size() > endWords.size())
24             return searchLadders(endWords, startWords, children, dict, ladder, ladders, flip);
25         for (string word : startWords) dict.erase(word);
26         for (string word : endWords) dict.erase(word);
27         unordered_set<string> intermediate;
28         bool done = false;
29         for (string word : startWords) {
30             string temp = word;
31             int len = word.length();
32             for (int p = 0; p < len; p++) {
33                 char letter = word[p];
34                 for (int i = 0; i < 26; i++) {
35                     word[p] = 'a' + i;
36                     if (endWords.find(word) != endWords.end()) {
37                         done = true;
38                         flip ? children[word].push_back(temp) : children[temp].push_back(word);
39                     }
40                     else if (!done && dict.find(word) != dict.end()) {
41                         intermediate.insert(word);
42                         flip ? children[word].push_back(temp) : children[temp].push_back(word);
43                     }
44                 }
45                 word[p] = letter;
46             }
47         }
48         return done || searchLadders(endWords, intermediate, children, dict, ladder, ladders, flip);
49     }
50     void genLadders(string& start, string& end, unordered_map<string, vector<string> >& children,
51                     vector<string>& ladder, vector<vector<string> >& ladders) {
52         if (start == end) {
53             ladders.push_back(ladder);
54             return;
55         }
56         for (string child : children[start]) {
57             ladder.push_back(child);
58             genLadders(child, end, children, ladder, ladders);
59             ladder.pop_back();
60         }
61     }
62 };

 

posted @ 2015-07-03 16:05  jianchao-li  阅读(340)  评论(0编辑  收藏  举报