地址:https://oj.leetcode.com/problems/word-ladder-ii/
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["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.
网上参考了一份代码( http://yucoding.blogspot.com/2014/01/leetcode-question-word-ladder-ii.html ), 主要是两个unordered_set, 一个是当前bfs要遍历的所有节点集合curs,一个是下次bfs要遍历的节点nxts,在遍历过程中,记录每个单词的所有前驱单词(用于最后构造路径),当检测到nxts中存在end时,说明已找到最短路径了,开始从end到start构建所有路径。
另外一个小细节是在bfs遍历过程中,遍历完curs后,在dict中删除curs中的所有元素,因为最短路径中一个单词只可能出现在某一层,既然在curs中出现了,就不应该在nxts中出现。这也避免了查重,节约了空间存储。
预处理也要注意一下,dict里插入start和end,不然要特殊判断,麻烦.
两次小改动AC,运行时间分别是1100ms+和1200ms+
参考代码
class Solution {
private:
unordered_map<string, vector<string>>findlast;
vector<vector<string>>ans;
public:
void findnext(string cur, unordered_set<string>&dict, unordered_set<string>&nxts)
{
string nxt;
for(int i = 0; i<cur.length(); ++i)
{
for(char ch = 'a'; ch<='z'; ++ch)
{
if(ch!=cur[i])
{
nxt = cur;
nxt[i] = ch;
if(dict.find(nxt)!=dict.end())
{
findlast[nxt].push_back(cur);
nxts.insert(nxt);
}
}
}
}
}
void bulitpath(vector<string>&vec, const string& start, const string& end)
{
if(end==start)
{
vector<string>v(vec.rbegin(), vec.rend());
ans.push_back(v);
}
for(int i = 0; i<findlast[end].size(); ++i)
{
vec.push_back(findlast[end][i]);
bulitpath(vec, start, findlast[end][i]);
vec.pop_back();
}
}
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
ans.clear();
unordered_set<string>curs, nxts;
curs.insert(start);
dict.insert(start);
dict.insert(end);
vector<string>vec;
vec.push_back(end);
while(!curs.empty())
{
for(auto it = curs.begin(); it != curs.end(); ++it)
dict.erase(*it);
for(auto it = curs.begin(); it != curs.end(); ++it)
findnext(*it, dict, nxts);
if(nxts.find(end)!=dict.end())
{
bulitpath(vec, start, end);
return ans;
}
curs = nxts;
nxts.clear();
}
return ans;
}
};