Given two words (beginWord and endWord), and a dictionary's word list, find the length of
shortest transformation sequence from beginWordto endWord, such that:
- Only one letter can be changed at a time
- 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 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.
难度:Medium
本来打算直接完成Word LadderII,但是还有BUG未解决,所以先把比较简单的这道题先完成。 这道题很容易想到利用宽度优先搜索解决。 建立一个队列,首先把beginWord加入队列中。用STL 中的map来记录每个单词的前一个单词(记为父单词),beginWord的父单词用“-”来标记。 当队列不为空的时候,取出队首,每一位分别用26个字母来替代后,判断是否为endWord,如果是,则endWord的父单词为当前这个单词,然后把endWord压入栈底,并从endWord开始,把所经过的单词(找到每个节点的父单词)压入栈,直到beginWord入栈。
把栈里所有元素装到一个向量里,则这个向量的大小就是这条路径的长度了,并且记录了这条路径所经过的所有单词(因为我是按照word LadderII的要求来写代码的,对于这道题这一步没有必要),如果存在这样的词梯,用一个变量flag来标记。 如果该单词在wordList中但是不是endWord,那么就把它送入队列,注意也要记录它的父单词,之后重新循环。被送入队列的单词从wordList中删除。
class Solution {
public:
int ladderLength (string beginWord, string endWord, unordered_set<string> &wordList) {
queue<string> myq;
myq.push(beginWord);
map<string,string> father;
father.insert(make_pair(beginWord,"-"));
vector<vector<string>> ans;
vector<vector<string>> realans;
int mark;
while(!myq.empty())
{
string s=myq.front();
if(wordList.count(s)!=0)
wordList.erase(s);
myq.pop();
for(int i = 0; i<s.size();i++)
{
for(int ii=0;ii<26;ii++)
{
char temp='a'+ii;
string str=s;
str[i]=temp;
if(str==endWord)
{
father[str]=s;
stack<string> mys;
mys.push(str);
father.insert(make_pair(str,s));
string st=str;
while(father[st]!="-")
{
mys.push(father[st]);
st=father[st];
}
vector<string> line;
while(!mys.empty())
{
line.push_back(mys.top());
mys.pop();
}
ans.push_back(line);
}
else if(str!=s&&wordList.count(str)!=0)
{
father.insert(make_pair(str,s));
wordList.erase(str);
myq.push(str);
}
}
}
}
if(ans.size()!=0)
mark=ans[0].size();
else
mark=0;
for(int i = 0;i<ans.size();i++)
{
int size=ans[i].size();
if(size <mark)
mark=ans[i].size();
}
for(int i = 0;i<ans.size();i++)
{
if(ans[i].size()==mark)
realans.push_back(ans[i]);
}
return mark;
}
};
之所以无法通过Word LadderII,是因为我错误地直接从wordList中删除了被送入队列的单词。 这样就可能导致无法找到所有的最短词梯。现在已经凌晨两点半了,等明天再完成Word Ladder II