终止条件:找到end单词或者层数超过字典大小+2
开始的想法:
bfs,像树的层序遍历一样,对于每层的每个词遍历一下字典,看字典中的每个单词是否符合ladder条件,若符合,加入到下一层,同时从字典里删除该词,效率太低,遍历字典效率是dict.size()*word_length(isNext的复杂度)
class Solution {
public:
//判断单词是否符合ladder条件
bool isNext(string str1, string str2)
{
if (str1.length() != str2.length())
return false;
int dif = 0;
for (unsigned i = 0; i<str1.length(); i++)
if (str1[i] != str2[i]){
dif++;
if (dif>1)
break;
}
return dif == 1 ? true : false;
}
int ladderLength(string start, string end, unordered_set<string> &dict) {
dict.erase(start);
dict.erase(end);
queue<string> queue;
int curCnt = 0, nextCnt = 1, level = 1, dictLen = dict.size(), minLen = dictLen + 3;
queue.push(start);
while (minLen == dictLen + 3 && level<minLen - 1 && !queue.empty()){
level++;
curCnt = nextCnt;
nextCnt = 0;
while (curCnt>0){
string str = queue.front();
queue.pop();
curCnt--;
if (isNext(str, end))
{
minLen = level;
break;
}
for (auto it = dict.begin(); it != dict.end(); )
{
if (isNext(str, *it))
{
queue.push(*it);
it = dict.erase(it);
nextCnt++;
}
else
it++;
}
}
}
return minLen == dictLen + 3 ? 0 : minLen;
}
};
上面的解法超时了,原因是遍历字典效率是dict.size()*word_length(isNext的复杂度),
还是上面的思想,bfs,像树的层序遍历一样,对于一层的每个单词,对每个位遍历26个字母,若变换后在字典中,加入到下一层,同时在字典里删除该词,复杂度26**word_length,
Tips:All words contain only lowercase alphabetic characters.这句话暗示了只有26个字母。。。看到这个就该留个心眼了。。。
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if(start.length()!=end.length())
return 0;
if(start==end)
return 1;
int level=1,curCnt=0,nextCnt=1,dictLen=dict.size(),minLen=dictLen+3;
queue<string> queue;
queue.push(start);
while(minLen==dictLen+3&&level<dictLen+2&&!queue.empty()){
level++;
curCnt=nextCnt;
nextCnt=0;
while(curCnt>0)
{
string str=queue.front();
queue.pop();
curCnt--;
for(int i=0;i<str.length();i++)
{
char temp=str[i];
for(char j='a';j<='z';j++)
{
if(j==temp)
continue;
str[i]=j;
if(str==end)
{
minLen=level;
break;
}
if(dict.find(str)!=dict.end()){
queue.push(str);
dict.erase(str);
nextCnt++;
}
}
str[i]=temp;
}
}
}
return minLen==dictLen+3?0:minLen;
}