Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
- Only one letter can be changed at a time.
- Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
Example 1:
Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
Example 2:
Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Output: 0
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
题意:
已知两个单词(起始单词和结束单词),一个单词词典,根据转换规则计算从起始单词到结束单词的最短转换步数。
转换规则如下:
1.转换时,只能转换单词中的1个字符。
2.转换得到的新单词,必须在单词词典中。
需要注意的是:
1.若无法转换到endWord,返回0。
2.所有单词长度相同。
3.只包含小写字符。
4.wordList中的无重复单词。
5.beginWord和endWord非空且不相同。
解法:
单词与单词之间的转换,可以理解为一张图,图的顶点为单词,若两单词之间可以互相转换,则这两个单词所代表的顶点间有一条边。求图中beginWord和endWord的所有路径中,最少包括多少个节点,即图的宽度优先搜索。
使用map构造邻接表表示的图,map定义为以string为key(图的顶点),vector<string>为value(代表图的各个顶点临接的顶点)如下图所示。
代码如下:
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList)
{
queue<pair<string, int>> log;
set<string> visited;
map<string, vector<string>> graph;
ConstructGraph(beginWord, wordList, graph);
visited.insert(beginWord);
log.push(pair<string, int>(beginWord, 1));
while(!log.empty())
{
string word = log.front().first;
int count = log.front().second;
log.pop();
if(word == endWord)
{
return count;
}
for(int i=0;i<graph[word].size();i++)
{
if(visited.find(graph[word][i]) == visited.end())
{
log.push(pair<string, int>(graph[word][i], count +1));
visited.insert(graph[word][i]);
}
}
}
return 0;
}
bool IsLadder(const string& firstWord, const string& secondWord)
{
int count = 0;
for(int i=0; i<firstWord.size();i++)
{
if(firstWord[i] != secondWord[i])
{
count++;
}
}
return count == 1;
}
void ConstructGraph(const string& beginWord, vector<string>& wordList, map<string, vector<string>>& graph)
{
wordList.push_back(beginWord);
for(int i=0; i<wordList.size();i++)
{
for(int j=i+1; j<wordList.size(); j++)
{
if(IsLadder(wordList[i], wordList[j]))
{
graph[wordList[i]].push_back(wordList[j]);
graph[wordList[j]].push_back(wordList[i]);
}
}
}
}
};