127. Word Ladder
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence frombeginWord to 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.
转载于点击打开链接
思路:把每一个单词看成一个节点,如果其他的单词与它只有一个字母不同,可以认为是该节点的邻居节点。这题可以看成是图的遍历,寻找从开始节点到结尾节点的最短路径。
BFS:
class Solution {
void addstring(string word,unordered_set<string> & wordList, queue<string> & tovisit)
{
wordList.erase(word);
for(int i=0;i<word.size();i++)
{
char letter=word[i];
for(int j=0;j<26;j++)
{
word[i]='a'+j;
if(wordList.find(word)!=wordList.end())
{
tovisit.push(word);
wordList.erase(word);
}
}
word[i]=letter;
}
}
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
wordList.insert(endWord);
int dis=2;
queue<string> tovisit;
addstring(beginWord,wordList,tovisit);//将其未访问过的邻居节点加入待访队列
while(tovisit.size()>0)
{
int num=tovisit.size();
for(int i=0;i<num;i++)
{
string word=tovisit.front();
tovisit.pop();
if(word==endWord) return dis;
addstring(word,wordList,tovisit);
}
dis++;
}
return 0;
}
};
BFS的改进:
从开始单词和结尾单词同时遍历,如果发现它们有共同的单词,说明已经找到了。
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
unordered_set<string> head,tail,*phead,*ptail;
head.insert(beginWord);
tail.insert(endWord);
int dis=2;
while(!head.empty()&&!tail.empty())
{
if(head.size()<tail.size())//保证phead指向较少元素的集合
{
phead=&head;
ptail=&tail;
}else
{
phead=&tail;
ptail=&head;
}
unordered_set<string> tmp;//存储当前单词的邻居,它是下一次遍历的对象
for(auto it=phead->begin();it!=phead->end();it++)
{
string word=*it;
wordList.erase(word);
for(int i=0;i<word.size();i++)
{
char letter=word[i];
for(int j=0;j<26;j++)
{
word[i]='a'+j;
if(ptail->find(word)!=ptail->end())
return dis;
if(wordList.find(word)!=wordList.end())
{
tmp.insert(word);
wordList.erase(word);
}
}
word[i]=letter;
}
}
dis++;
swap(tmp,*phead);
}
return 0;
}
};