Man it took me numerous submissions to get AC, and I referred to this link: http://yihuad.blogspot.com/2013/11/word-ladder-ii-leetcode.html
Idea is pretty simple: since there's strict memory limit, we can simply organize the original dictionary as a DAG, by using BFS - by so, there could be only ONE copy of the whole dictionary. Then DFS could be used to retrieve all pathes.
class Solution { public: void buildPath(string curr, string end, vector<string> rec, vector<vector<string>> &ret, unordered_map<string, vector<string>> &dag) { rec.push_back(curr); if (curr == end) { size_t currLen = rec.size(); if (ret.empty()) ret.push_back(rec); else { size_t currRetLen = ret[0].size(); if (currLen < currRetLen) { ret.clear(); ret.push_back(rec); } else if (currLen == currRetLen) { ret.push_back(rec); } } return; } vector<string> &nexts = dag[curr]; for (auto it = nexts.begin(); it != nexts.end(); it++) { vector<string> currrec = rec; buildPath(*it, end, currrec, ret, dag); } } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { unordered_map<string, vector<string>> dag; dict.insert(start); dict.insert(end); vector<unordered_set<string>> q(2); int cur = 0, next = 1; q[cur].insert(start); while (!q[cur].empty()) { for (auto it = q[cur].begin(); it != q[cur].end(); it++) dict.erase(*it); for (auto it = q[cur].begin(); it != q[cur].end(); it++) { string str = *it; for (int i = 0; i < str.length(); i++) { char tmp = str[i]; for (char k = 'a'; k <= 'z'; ++k) { if (k == tmp) continue; str[i] = k; if (dict.find(str) != dict.end()) { dag[*it].push_back(str); q[next].insert(str); } } str[i] = tmp; } } // rolling array q[cur].clear(); cur = cur == 0 ? 1 : 0; next = next == 0 ? 1 : 0; } vector<vector<string>> ret; vector<string> rec; buildPath(start, end, rec, ret, dag); return ret; } };