题目127:Word Ladder
题目描述:
Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformation sequence from beginWord to endWord, 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”]
As one shortest transformation is “hit” -> “hot” -> “dot” -> “dog” -> “cog”,
return its length 5.
Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
题目分析:
给定一个字典,一个beginWord和一个endWord,求从begin到end的最短路径,广度优先搜索,bfs适合求最短路径、树最小深度问题。
广度优先搜索,使用辅助队列,从beginWord开始,如果其相邻的单词在字典中,则添加到队列中;相邻单词指beginWord中任意一个字母改变成的新单词。为了防止出现死循环,如hot->dot->hot,加入队列后要从字典中删除或者采用visit数组标明是否已访问。求最短路径,需要求从beginWord到endWord的深度,必须知道每层的结束位置,所以可以添加特殊符号确定结束位置。
int ladderlength(string beginWord, string endWord, unordered_set<string> &wordDict) {
if (wordDict.size() == 0)
return 0;
queue<string> que;
que.push(beginWord);
que.push("");
int res = 1;
while (!que.empty()) {
string up = que.front();
que.pop();
if (up != "") {
int i, uplen;
char c, ch;
uplen = up.size();
for (i = 0; i < uplen; i ++) {
ch = up[i];
for (c = 'a'; c <= 'z'; c ++) {
up[i] = c;
if (c == ch)
continue;
if (up == endWord)
return res + 1;
if (wordDict.find(up) != wordDict.end()) {
que.push(up);
wordDict.erase();
}
}
up[i] = ch;
}
} else if (!que.empty()) {
/*
* 到达当前层的结尾,当前层的结点都出队列,当前层的
* 子结点都入队列,且当前层不能是最后一层。
*/
++ res;
que.push("");
}
}
return 0;
};
稍加修改,就可以改成使用visit数组记录是否访问。
unordered_set<string> visit;
/*
* 判断是否需要入队列条件,同时判断是否被访问过,只有没有被访问的
* 结点才可以入队列
*/
if (wordDict.find(up) != wordDict.end() && visit.find(up) == visit.end()) {
que.push(up);
visit.insert(up);
}