题目链接
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 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.
这道题就是我们所谓的词梯,每次只变换一个字母,从一个单词变换到另一个单词,求出梯数,即变换步数+1
这道题还是挺简单的,用DFS,或者BFS可以做,但是DFS会超时,原因是DFS的回溯浪费了时间,而BFS避免了这种情况,因为题目只需要求步数,也就是我们一般在求一个二叉树的层数的做法,求二叉树时候我们会有一个标志变量current_num来表示当前层的结点数,同样的,由于这道题中我们不能很直接的知道每一层的终点,所以就加个变量next_num来表示下一层的结点数,从而顺利的广度搜索
另外这道题还让我增加了对头文件unordered_set的了解,有兴趣的也可以了解一下unordered_set
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
#include <unordered_set>
using namespace std;
int ladderLength(string start, string end, unordered_set<string>& dict) {
if (start.size() != end.size())
return 0;
if (start == end)
return 2;
unordered_set<string> answer;
answer.insert(start);
int current_num = 1;
int next_num = 0;
queue<string> que;
que.push(start);
int length = 0;
while (current_num > 0)
{
string temp_string = que.front();
que.pop();
current_num--;
for (int i = 0; i< temp_string.size(); i++)
{
string temp = temp_string;
for (char ch = 'a'; ch <= 'z'; ch++)
{
temp[i] = ch;
if (dict.find(temp) != dict.end() && answer.find(temp) == answer.end())
{
if (temp == end)
{
return length + 2;
}
else
{
answer.insert(temp);
que.push(temp);
next_num++;
}
}
}
}
if (current_num == 0)
{
current_num = next_num;
next_num = 0;
length++;
}
}
return 0;
}
int main()
{
string start = "a";
string end = "c";
unordered_set<string> dict;
dict.insert("a");
dict.insert("b");
dict.insert("c");
cout << ladderLength(start, end, dict) << endl;
system("pause");
}