您的位置:首页 > 其它

Word Ladder II

2014-04-06 20:30 232 查看
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.
与Word Ladder题目类似,但需要记录每条从start到end的路径。路径的记录方式,标记每个word的father word。注意本题要求的是所有的shortest path,即结果中的每条path的长度相同,每个word可以有多个father,但必须都来自同一层。

使用两个unordered_set用作ping-pong队列,逐层访问。

用visited标记已访问过的word时需要注意,不能立即将得到的新词添加到visited中,因为从上一层中别的word还有可能到达该词,而这些路径必须都保存。因此,在扩展新的层次之前,将上一层的所有节点标记为visited。

当找到end时,没必要再进行下一次层次的遍历,但该层次的所有word必须遍历完成。

恢复路径的时候,从end节点开始,利用保存的father信息进行DFS遍历,找到所有的路径并保存。

代码如下:

class Solution {
public:
vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {

unordered_set<string> visited;
unordered_set<string> queue1, queue2;
unordered_map<string, vector<string> > f;

bool flag = false;

queue1.insert(start);
while(!queue1.empty() && !flag)
{
for(auto str: queue1)
{
visited.insert(str);
}
for(auto str: queue1)
{
for(int i=0; i<str.size(); i++)
{
string old = str;
for(char c = 'a'; c <= 'z'; c++)
{
if(c == str[i]) continue;

swap(str[i], c);

if((dict.find(str) != dict.end() || str == end)
&& visited.find(str) == visited.end())
{
queue2.insert(str);
f[str].push_back(old);
}
if(str == end) flag = true;
swap(str[i], c);
}
}
}
queue1.clear();
swap(queue1, queue2);
}
vector<string> path;
vector<vector<string> > result;
if(flag)
{
path.push_back(end);
dfs(f, path, result, start);
}
return result;
}

void dfs(unordered_map<string, vector<string> > &f, vector<string> &path, vector<vector<string> > &result, string start)
{
if(path.back() == start)
{
result.push_back(path);
std::reverse(result.back().begin(), result.back().end());
return;
}

string cur = path.back();
vector<string> &fathers = f[cur];
for(int i=0; i<fathers.size(); i++)
{
path.push_back(fathers[i]);
dfs(f, path, result, start);
path.pop_back();
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: