最近重新捡起算法来看,发现广度优先搜索的代码不是很熟,就在leetcode上搜了一下,找到这道题练练,还是发现了很多问题的。
题目描述:
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.
由于事先知道是广度搜索,这道题目大体思路还是比较明确的,字典里存储可能的状态,定义数据结构存储队列中的字符串和当前的路径。代码如下:
class Solution {
public:
struct data
{
string s;
int length;
};
bool compareWords(string word1,string word2)
{
int length=word1.length();
int count=0;
for(int i=0;i<length;i++)
{
if(word1[i]!=word2[i])
count++;
}
return count==1;
}
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
queue<data>q;
data beginData;
unordered_set<string> wordListCopy;
beginData.s=beginWord;beginData.length=0;
int length=0;
q.push(beginData);
while(!q.empty())
{
data tempData;
beginData=q.front();
q.pop();
if(compareWords(beginData.s,endWord))
return beginData.length+1;
for(auto &word :wordList)
if(wordListCopy.find(word)==wordListCopy.end()&&compareWords(beginData.s,word))
{
tempData.s=word;
tempData.length=beginData.length+1;
q.push(tempData);
wordListCopy.insert(word);
}
}
return length;
}
};
上述代码运行最后超时了,但是感觉思路是对的,上网看了下别人的思路后,主要是在判断两个字符串是否只相差一个字符的时候算法复杂度为 O(n2) 。一般别人采用的都是对原始字符串每个位置进行替换的策略,复杂度可以降到 O(n) ,同时利用两个全局变量分别保存状态转移的数目和每一个状态下的数目,这样就可以不用定义数据结构表示每一个状态了。代码如下
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
queue<string>q;
q.push(beginWord);
int length = beginWord.size();
int count = 1, level = 0;
string s;
while (!q.empty())
{
s = q.front();
q.pop();
for (int i = 0; i < length;i++)
for (char c = 'a'; c <= 'z'; c++)
{
if (c == s[i]) continue;
swap(c, s[i]);
if (s == endWord)
return level+2;
if (wordList.find(s) != wordList.end())
{
q.push(s);
wordList.erase(s);
}
swap(c, s[i]);
}
count--;
if (count == 0)
{
count = q.size();
level++;
}
}
return 0;
}
};