1 class Solution {
2 public:
3 vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
4 // Start typing your C/C++ solution below
5 // DO NOT write int main() function
6 vector<vector<string> > result;
7 unordered_map<string, unordered_set<string> > adj_set;
8 queue<pair<vector<string>, int> > path;
9 path.push(make_pair(vector<string>(1, start), 0));
10 string cur_string = start, str_left, str_right, str_conv;
11 vector<string> cur_path;
12 int min_step = dict.size() + 1;
13 int cur_step;
14 int last_len = 0;
15 string last_string;
16 unordered_set<string> visited;
17 visited.insert(start);
18
19 // build adj_set
20 unordered_set<string> cur_set_start;
21 for (int i = 0; i < cur_string.length(); ++i) {
22 str_left = cur_string.substr(0, i);
23 str_right = cur_string.substr(i + 1, cur_string.length() - i - 1);
24 for (char c = 'a'; c <= 'z'; ++c) {
25 str_conv = str_left;
26 str_conv.append(1, c);
27 str_conv.append(str_right);
28 if (((dict.find(str_conv) != dict.end()) && (0 != cur_string.compare(str_conv)))
29 || (0 == str_conv.compare(end))) {
30 cur_set_start.insert(str_conv);
31 }
32 }
33 }
34 adj_set.insert(make_pair(cur_string, cur_set_start));
35 for (unordered_set<string>::iterator iter = dict.begin();
36 iter != dict.end(); ++iter) {
37 unordered_set<string> cur_set;
38 cur_string = *iter;
39 for (int i = 0; i < cur_string.length(); ++i) {
40 str_left = cur_string.substr(0, i);
41 str_right = cur_string.substr(i + 1, cur_string.length() - i - 1);
42 for (char c = 'a'; c <= 'z'; ++c) {
43 str_conv = str_left;
44 str_conv.append(1, c);
45 str_conv.append(str_right);
46 if (((dict.find(str_conv) != dict.end()) && (0 != cur_string.compare(str_conv)))
47 || (0 == str_conv.compare(end))) {
48 cur_set.insert(str_conv);
49 }
50 }
51 }
52 adj_set.insert(make_pair(cur_string, cur_set));
53 }
54
55 while (!path.empty()) {
56 cur_path = path.front().first;
57 cur_string = cur_path.at(cur_path.size() - 1);
58 cur_step = path.front().second;
59 if (cur_step > last_len) {
60 visited.insert(cur_string);
61 last_string = cur_string;
62 } else if (cur_step == last_len
63 && (0 != last_string.compare(cur_string))) {
64 visited.insert(cur_string);
65 last_string = cur_string;
66 }
67
68 if (0 == cur_string.compare(end)) {
69 result.push_back(cur_path);
70 path.pop();
71 continue;
72 }
73
74 if (cur_step + 1 > min_step) {
75 path.pop();
76 continue;
77 }
78
79 unordered_set<string> cur_adj_set = adj_set.find(cur_string)->second;
80 for (unordered_set<string>::iterator iter = cur_adj_set.begin();
81 iter != cur_adj_set.end(); ++iter) {
82 str_conv = *iter;
83 if (0 == str_conv.compare(end)) {
84 if ((cur_step + 1) < min_step) {
85 min_step = cur_step + 1;
86 }
87 }
88 if (visited.find(str_conv) == visited.end()) {
89 cur_path.push_back(str_conv);
90 path.push(make_pair(cur_path, cur_step + 1));
91 cur_path.pop_back();
92 }
93 }
94 path.pop();
95 }
96 return result;
97 }
98 };