Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence frombeginWord toendWord, such that:
1. Only one letter can be changed at a time
2. Each intermediate word must exist in the word list
For example, Given:
beginWord = "hit",
endWord = "cog"
wordList =
["hot","dot","dog","lot","log"]
As one shortest transformation is
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
, return its length5
.
Note:
1. Return 0 if there is no such transformation sequence.
2. All words have the same length.
3. All words contain only lowercase alphabetic characters.
在做另一门作业的时候,突然发现了这道题。题目背景差不多,但要求的内容不一样,所以动手做了做。
因为求的是最短的词梯长度,即两个词之间的最短路径,所以又想到了bfs。可以将题目转变为"求无向图中,某两点之间的最短路径"的问题。两个单词之间若只有一个字母的差异,则对应的两点之间存在边。因此,只需要从起点开始,对整个图进行宽度搜索,计算搜索到第几层时第一次遇到目标单词,就能得到题目所求。如果完成了遍历仍没有找到目标单词,说明词梯不存在。
宽搜的方法是依次用'a'到'z'替换当前词的每一位,检索替换后得到的单词是否在字典之中。所以,搜索前需要将起始单词从字典中删除,将目标单词加入字典中。此外,每遍历到一个位于字典中的单词之后,可将其从字典中删除。因为题目仅需求出最短路径的长度,这样可以防止重复的情况发生。
同时,用cnt来记录宽搜的层数,初始值为1;利用队列来记录宽搜的过程;在对单词字母进行替换时,需要保存单词的原型。
下列代码是在参考他人想法的基础上完成的~
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string>& wordList){
int cnt = 1;
queue<string> q;
q.push(start);
wordList.insert(end);
wordList.erase(start);
while(!q.empty()){
cnt++;
int size = q.size();
for(int t = 0; t < size; t++){
string s(q.front());
q.pop();
string tmp = s;
for(int i = 0; i < start.length(); i++){
for(char j = 'a'; j <= 'z'; j++){
s[i] = j;
if(s==end) return cnt;
if(wordList.find(s)!=wordList.end()){
wordList.erase(s);
q.push(s);
}
s = tmp;
}
}
}
}
return 0;
}
};