# 单词接龙 II

按字典 wordList 完成从单词 beginWord 到单词 endWord 转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk 这样的单词序列,并满足:

给你两个单词 beginWordendWord ,以及一个字典 wordList 。请你找出并返回所有从 beginWordendWord最短转换序列 ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表 [beginWord, s1, s2, ..., sk] 的形式返回。

 

示例 1:

输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
解释:存在 2 种最短的转换序列:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"

示例 2:

输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:[]
解释:endWord "cog" 不在字典 wordList 中,所以不存在符合要求的转换序列。

 

提示:

以下错误的选项是?

## aop ### before ```cpp #include using namespace std; ``` ### after ```cpp int main() { Solution sol; vector> res; string beginWord = "hit", endWord = "cog"; vector wordList = {"hot", "dot", "dog", "lot", "log", "cog"}; res = sol.findLadders(beginWord, endWord, wordList); for (auto i : res) { for (auto j : i) cout << j << " "; cout << endl; } return 0; } ``` ## 答案 ```cpp class Solution { public: unordered_map> tree; vector> ans; void dfs(vector &cur, string curWord, string endWord) { if (curWord == endWord) { ans.push_back(cur); return; } for (string s : tree[curWord]) { cur.push_back(s); dfs(cur, s, endWord); cur.pop_back(); } } vector> findLadders(string beginWord, string endWord, vector &wordList) { if (wordList.size() == 0 || find(wordList.begin(), wordList.end(), endWord) == wordList.end()) return {}; unordered_set bfsFromBegin{beginWord}; unordered_set bfsFromEnd{endWord}; unordered_set dirc(wordList.begin(), wordList.end()); bool findFlag = false, reverseFlag = false; while (!bfsFromBegin.empty()) { unordered_set next; for (string s : bfsFromBegin) dirc.erase(s); for (string s1 : bfsFromBegin) { for (int i = 0; i < s1.size(); ++i) { string s2 = s1; for (char c = 'a'; c <= 'z'; ++c) { s2[i] = c; if (dirc.count(s2) == 0) continue; next.insert(s2); } reverseFlag ? tree[s2].push_back(s1) : tree[s1].push_back(s2); } } bfsFromBegin = next; if (bfsFromBegin.size() > bfsFromEnd.size()) { reverseFlag = !reverseFlag; swap(bfsFromBegin, bfsFromEnd); } if (findFlag) break; } vector cur = {beginWord}; dfs(cur, beginWord, endWord); return ans; } }; ``` ## 选项 ### A ```cpp class Solution { public: bool differ_one(string &s, string &t) { int n = 0; for (int i = 0; i < s.size(); ++i) if ((n += s[i] != t[i]) > 1) return false; return n == 1; } vector> fa; vector tmp; vector> ans; void dfs(int index, vector &wordList) { if (fa[index].empty()) { reverse(tmp.begin(), tmp.end()); ans.push_back(tmp); reverse(tmp.begin(), tmp.end()); } for (auto &x : fa[index]) { tmp.push_back(wordList[x]); dfs(x, wordList); tmp.pop_back(); } } vector> findLadders(string beginWord, string endWord, vector &wordList) { int b = -1, e = -1, x; for (int i = 0; i < wordList.size(); ++i) { if (wordList[i] == beginWord) b = i; if (wordList[i] == endWord) e = i; } if (e == -1) return ans; if (b == -1) wordList.push_back(beginWord), b = wordList.size() - 1; queue que; fa.assign(wordList.size(), vector()); vector index(wordList.size(), 0); que.push(b), index[b] = 1; while (!que.empty()) { x = que.front(), que.pop(); if (index[e] && index[x] >= index[e]) break; for (int i = 0; i < wordList.size(); ++i) if ((index[i] == 0 || index[x] + 1 == index[i]) && differ_one(wordList[x], wordList[i])) if (index[i] == 0) index[i] = index[x] + 1, que.push(i), fa[i].push_back(x); else fa[i].push_back(x); } if (index[e] == 0) return ans; tmp.push_back(endWord); dfs(e, wordList); tmp.pop_back(); return ans; } }; ``` ### B ```cpp class Solution { public: vector> findLadders(string beginWord, string endWord, vector &wordList) { unordered_set list(wordList.begin(), wordList.end()); if (!list.count(endWord)) return {}; unordered_map> trace; unordered_set p; unordered_set q{beginWord}; while (q.size() && !trace.count(endWord)) { for (auto w : q) { list.erase(w); } p.clear(); for (auto str : q) { for (int i = 0; i < str.size(); ++i) { string tmp = str; for (char c = 'a'; c <= 'z'; ++c) { tmp[i] = c; if (list.find(tmp) == list.end()) continue; trace[tmp].insert(str); p.insert(tmp); } } } q = p; } if (!trace.size()) return {}; vector> res; dfs(res, {}, trace, endWord); return res; } void dfs(vector> &res, vector path, unordered_map> &trace, string &str) { path.push_back(str); if (trace.count(str) == 0) { reverse(path.begin(), path.end()); res.push_back(path); return; } for (auto word : trace[str]) dfs(res, path, trace, word); } }; ``` ### C ```cpp class Solution { public: vector> findLadders(string beginWord, string endWord, vector &wordList) { vector> ans; unordered_set dict(wordList.begin(), wordList.end()); vector p{beginWord}; queue> paths; paths.push(p); unordered_set words; int level = 1, minlength = INT_MAX; while (!paths.empty()) { vector t = paths.front(); paths.pop(); if (t.size() > level) { for (string s : words) dict.erase(s); words.clear(); level = t.size(); if (level > minlength) break; } string last = t.back(); for (int i = 0; i < last.size(); ++i) { string newlast = last; for (char ch = 'a'; ch <= 'z'; ++ch) { newlast[i] = ch; if (!dict.count(newlast)) continue; words.insert(newlast); vector nextpath = t; nextpath.push_back(newlast); if (newlast == endWord) { ans.push_back(nextpath); minlength = level; } else { paths.push(nextpath); } } } } return ans; } }; ```