题目:
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.
这个题是真的烦,MLE,TLE,CLE真的是服了。
言归正传,经典题。将每个单词抽象成节点,相差一个字母的两个单词连边。
此题要求输出最短的词梯,所以使用bfs,找到最短词梯的长度。
题目还要输出所有的最短词梯,且考虑到所有最短词梯构成的并不一定是树,所以要使用dfs在bfs访问过的节点的基础上再次搜索。
为了方便dfs,在bfs的时候记录每个节点的step(从起始节点到当前节点的词梯长度),依据这个参数我们就可以还原bfs的搜索顺序了。
通过这个题,我还知道了,原来map中count比取值要快辣么多。。。。
class Solution {
public:
vector< vector<string> > ans;
vector<string> word;
vector<bool> vis;
unordered_map<string, int> mp;
vector<int> q;
vector<string> tans;
vector<int> step;
int minstep;
vector< vector<string> > findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {
minstep = -1;
prep(wordList);
bfs(mp[beginWord], mp[endWord]);
if (minstep != -1) {
tans.clear();
tans.resize(minstep + 1);
dfs(mp[endWord]);
}
return ans;
}
void prep(unordered_set<string> &wordList) {
mp.clear();
ans.clear();
word.clear();
word.push_back("null");
unordered_set<string>::iterator it;
int cnt = 0;
for (it = wordList.begin(); it != wordList.end(); it++) {
mp[*it] = ++cnt;
word.push_back(*it);
}
vis.resize(cnt + 1);
step.resize(cnt + 1);
}
void bfs(int ax, int ay) {
int h = 0, t = 1;
q.clear();
q.push_back(ax);
vis[ax] = true;
step[ax] = 0;
int len, num, sto;
char cc;
while (h < t) {
num = q[h];
if (num == ay) {
minstep = step[num];
return;
}
string str = word[num];
len = str.length();
for (int j = 0; j < len; j++) {
cc = str[j];
for (char k = 'a'; k <= 'z'; k++) {
if (cc != k) {
str[j] = k;
if (mp.count(str) == 0) continue;
sto = mp[str];
if (!vis[sto]) {
q.push_back(sto);
vis[sto] = true;
step[sto] = step[num] + 1;
t++;
}
}
}
str[j] = cc;
}
h++;
}
}
void dfs(int x) {
tans[step[x]] = word[x];
if (step[x] == 0) {
ans.push_back(tans);
return;
}
string str = word[x];
int len = str.length();
for (int j = 0; j < len; j++) {
char cc = str[j];
for (char k = 'a'; k <= 'z'; k++) {
if (cc != k) {
str[j] = k;
if (mp.count(str) == 0) continue;
int sto = mp[str];
if (vis[sto] && step[sto] + 1 == step[x]) dfs(sto);
}
}
str[j] = cc;
}
}
};