leetcode 126 Word Ladder II
原题链接:https://leetcode.com/problems/word-ladder-ii/
Description
Given two words (beginWord and endWord), and a dictionary’s word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the word list
For example,
Given:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,”dot”,”dog”,”lot”,”log”]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
Solution
跟127那道题差不多,只不过多了要保存路径(所有解)。
一开始用dfs结果超时,一看要求最短路径马上就想到了bfs。
于是胡乱一敲提交上去tle QAQ。
bfs太慢好吧那么来个双向的吧,不幸的是经过一些奇怪的姿势,只能水到31组数据
然后一直wa(总是少了几组解),越写越烦懒得改了。网上搜题解才搞明白了。
具体做法是: 分层bfs,每遍历完一层再扩展下一层。在扩展过程中记得用map
保存新节点和旧节点的父子关系,同时在dic中删除已出现的word防止重复。
最后利用得到的这个map从end出发找start。好了终于过了 卒...
talk is cheap show me the code
class Solution {
using ves = vector<string>;
using vees = vector<ves>;
using Hash = map<string, vector<string>>;
public:
vees findLadders(string start, string end, unordered_set<string> &dic) {
if(!bfs(start, end, dic)) return ans;
ves rec;
dfs(start, end, rec);
return ans;
}
private:
void dfs(string &start, string &end, ves &rec) {
rec.push_back(end);
if(start == end) {
ves temp(rec);
reverse(temp.begin(), temp.end());
ans.push_back(temp);
rec.pop_back();
return;
}
for(auto &r: hsh[end]) {
dfs(start, r, rec);
}
rec.pop_back();
}
bool bfs(string start, string end, unordered_set<string> &dic) {
int cur = 0;
unordered_set<string> Q[2];
Q[cur].insert(start);
auto expandState = [&](unordered_set<string> &from, unordered_set<string> &to) {
to.clear();
for(auto &r: from) {
for(int i = 0; i < (int)r.size(); i++) {
string temp = r;
for(char j = 'a'; j <= 'z'; j++) {
char ch = temp[i];
if(ch == j) continue;
temp[i] = j;
if(dic.find(temp) != dic.end()) {
to.insert(temp);
hsh[temp].push_back(r);
}
temp[i] = ch;
}
}
}
};
while(!Q[cur].empty()) {
for(auto &r: Q[cur]) dic.erase(r);
expandState(Q[cur], Q[cur ^ 1]);
cur ^= 1;
if(Q[cur].find(end) != Q[cur].end()) return true;
}
return false;
}
private:
Hash hsh;
vees ans;
};