void buildPaths(const string& word, const string& beginWord, const unordered_map<string, vector<string>>& parents, vector<string>& path, vector<vector<string>>& result) { if (word == beginWord) { result.push_back(vector<string>(path.rbegin(), path.rend())); return; } for (const string& p: parents.at(word)) { path.push_back(p); buildPaths(p, beginWord, parents, path, result); path.pop_back(); } }
void buildPaths(string &start, string &end, unordered_map<string, vector<string> > &m, vector<string> &path, vector< vector<string> > &result) { if (end == start) { vector<string> clone(path); clone.insert(clone.begin(), start); result.push_back(clone); return; } path.insert(path.begin(), end); for (int i=0; i < m[end].size(); ++i) { buildPaths(start, m[end][i], m, path, result); } path.erase(path.begin()); }
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) { unordered_set<string> dict(wordList.begin(), wordList.end()); if (!dict.count(endWord)) return {}; dict.erase(endWord); queue<string> q; q.push(beginWord); unordered_map<string, vector<string>> parents; unordered_map<string, int> levels; levels[beginWord] = 1; int level = 0; bool found = false; while (!q.empty() && !found) { level ++; for (int size = q.size(); size > 0; size--) { string tmp = q.front(); q.pop(); for (int i=0; i < tmp.size(); i++) { string temp = tmp; for (char c='a'; c <= 'z'; c++) { if (c == tmp[i]) continue; temp[i] = c; if (temp == endWord) { parents[temp].push_back(tmp); found = true; } else if (levels.count(temp) && level < levels.at(temp)) { parents[temp].push_back(tmp); } if (!dict.count(temp)) continue; dict.erase(temp); q.push(temp); levels[temp] = levels.at(tmp) + 1; parents[temp].push_back(tmp); } } } } vector<vector<string>> result; if (found) { vector<string> path{endWord}; buildPaths(endWord, beginWord, parents, path, result); } return result; }
vector< vector<string> > findLadders(string start, string end, unordered_set<string> &dict) { vector<vector<string> > result; queue<string> q; q.push(start); unordered_set<string> visited; visited.insert(start); unordered_map<string, vector<string> > m; unordered_map<string, int> level; level[start] = 1; int maxLevel = -1; while (!q.empty()) { string tmp = q.front(); q.pop(); if (maxLevel != -1 && level[tmp] > maxLevel) { break; } for (int i=0; i < tmp.size(); i++) { for (char c='a'; c <= 'z'; c++) { if (c == tmp[i]) continue; string temp = tmp; temp[i] = c; if (temp == end) { maxLevel = level[tmp]; if (m.find(end) == m.end()) { m[end] = vector<string>(); } m[end].push_back(tmp); } else if (dict.find(temp) != dict.end()) { if (visited.find(temp) == visited.end()) { q.push(temp); visited.insert(temp); m[temp] = vector<string>(); m[temp].push_back(tmp); level[temp] = level[tmp] + 1; } else if (level[tmp]+1 == level[temp]) { m[temp].push_back(tmp); } } } } } vector<string> path; buildPaths(start, end, m, path, result); return result; }