题目描述
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence 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"]
As one shortest transformation is"hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length5.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- 和当前单词相邻的单词,就是和顶点共边的另一个顶点,是对当前单词改变一个字母且在字典内存在的单词
- 找到一个单词的相邻单词,加入BFS队列后,我们要从字典内删除,因为不删除会造成类似hog->hot->hog这样的死循环。而且删除对求最短路径没有影响,因为我们第一次找到的单词肯定是最短路径,我们是层序遍历去搜索的,最早找到的一定是最短路径,即使后面的其他单词也能转换成它,路径肯定不会比当前的路径短。这道题仅要求求出最短路径长度,不需要求输出最短路径,所以可以删除这个单词。
- BFS队列之间用空串“”来标示层与层的间隔,每次碰到层的结尾,遍历深度+1,进入下一层。
- int path = 1;
3. 我们在改变一个单词的每一个字母时,需要首先保存这个字符,然后再去搜索匹配。最后全部搜索完,还需要恢复现场。
- char tmp = str[i];
- str[i] = tmp; //重置回原来的单词
(1) | iterator erase (const_iterator position); |
---|
(2) | size_type erase (const value_type& val); |
---|
(3) | iterator erase (const_iterator first, const_iterator last); |
---|
- if(str == end) return path + 1; //如果改变后的单词等于end 返回path+1
复杂度:最坏情况就是把所有长度为L的字符串都看一遍,或者字典内的字符串都看一遍。长度为L的字符串总共有26^L.时间复杂度O(26^L),空间上需要存储访问情况,O(size(dict)).
实现代码:
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if(start.size() == 0 || end.size() == 0) return 0;
queue<string> wordQ; //创建一个string类型队列;
wordQ.push(start);
wordQ.push("");
int path = 1;
while(!wordQ.empty())
{
string str = wordQ.front(); //返回队首元素的值,但不删除该元素;
wordQ.pop(); //删除队列首元素但不返回其值
if(str != "")
{
int len = str.size();
for(int i = 0; i < len; i++)
{
char tmp = str[i];
for(char c = 'a'; c <= 'z'; c++)
{
if(c == tmp) continue;
str[i] = c;
if(str == end) return path + 1; //如果改变后的单词等于end 返回path+1
if(dict.find(str) != dict.end())
{
wordQ.push(str);
dict.erase(str); //字典内删除这个词 防止反复走
}
}
str[i] = tmp; //重置回原来的单词
}
}
else
if(!wordQ.empty())
{
//到达当前层的结尾,并且不是最后一层的结尾
path++;
wordQ.push("");
}
}
return 0;
}
};