Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,
Given:
start =“hit”
end =“cog”
dict =[“hot”,“dot”,“dog”,“lot”,“log”]
As one shortest transformation is"hit" -> “hot” -> “dot” -> “dog” -> “cog”,
return its length5.
Note:
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
//DFS 空间过大
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict)
{
if (start == end)
return 1;
int Res = INT_MAX;
vector<bool> bvec(dict.size(), false);
vector< vector<string> > res;
vector<string> tmp;
tmp.push_back(start);
Find(start, end, dict, bvec, res, tmp);
for(int i=0;i<res.size();i++)
{
Res = Res < res[i].size()?Res:res[i].size();
//for (int j=0;j<res[i].size();j++)
//cout<<res[i][j]<< " ";
//cout<<endl;
}
return Res;
}
void Find(string cur, string end, unordered_set<string> &dict, vector<bool> &bvec, vector< vector<string> > &res, vector<string> &tmp)
{
if (IfOneDiff(cur,end))
{
tmp.push_back(end);
res.push_back(tmp);
tmp.pop_back();
}
unordered_set<string> ::iterator iter = dict.begin();
for (int i=0;i<dict.size();i++,iter++)
{
if (!bvec[i] && IfOneDiff(cur, *iter))
{
tmp.push_back(*iter);
bvec[i] = true;
Find(*iter, end, dict, bvec, res, tmp);
bvec[i] = false;
tmp.pop_back();
}
}
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
//DFS 去掉额外空间 时间太久
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict)
{
if (start == end)
return 1;
int res = INT_MAX;
vector<bool> bvec(dict.size(), false);
vector<string> tmp;
tmp.push_back(start);
Find(start, end, dict, bvec, res, tmp);
return res;
}
void Find(string cur, string end, unordered_set<string> &dict, vector<bool> &bvec, int &res, vector<string> &tmp)
{
if (IfOneDiff(cur,end))
{
tmp.push_back(end);
res = res<tmp.size()?res:tmp.size();
tmp.pop_back();
return;//发现提前退出,不需要继续查找
}
unordered_set<string> ::iterator iter = dict.begin();
for (int i=0;i<dict.size();i++,iter++)
{
if (!bvec[i] && IfOneDiff(cur, *iter))
{
tmp.push_back(*iter);
bvec[i] = true;
Find(*iter, end, dict, bvec, res, tmp);
bvec[i] = false;
tmp.pop_back();
}
}
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
//此题目适合用BFS,因为BFS能很快获得最小次数而提前终止,DFS则不能
//BFS
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict)
{
queue<pair<string, int> > que;
que.push(make_pair(start, 1));
dict.insert(end);
unordered_set<string> ::iterator it = dict.find(start);//去掉start 不去也行
if (it != dict.end())
dict.erase(it);
while(!que.empty())
{
pair<string, int> tmp = que.front();
int size = dict.size();
que.pop();
unordered_set<string> ::iterator iter = dict.begin();
if (tmp.first == end)
return tmp.second;
for (int i=0;i<size;i++)
{
if (IfOneDiff(tmp.first, *iter))
{
que.push(make_pair(*iter, tmp.second+1));
dict.erase(iter++);//这里一定要去掉 不然时间太久不通过
}
else
iter++;
}
}
return 0;
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
//BFS 修改
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict)
{
queue<pair<string, int> > que;
que.push(make_pair(start, 1));
dict.insert(end);
unordered_set<string> ::iterator it = dict.find(start);//去掉start 不去也行
if (it != dict.end())
dict.erase(it);
while(!que.empty())
{
pair<string, int> tmp = que.front();
int size = dict.size();
que.pop();
unordered_set<string> ::iterator iter = dict.begin();
if (tmp.first == end)
return tmp.second;
while (dict.end() != iter)
{
if (IfOneDiff(tmp.first, *iter))
{
que.push(make_pair(*iter, tmp.second+1));
//前面一层遍历过的,后面不需要再重复,重复的话肯定不是最小
//会改变传入的dict,或者也可以用bool标记每个是否被遍历过
dict.erase(iter++);//这里一定要去掉 不然时间太久不通过
}
else
iter++;
}
}
return 0;
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
测试
#include<vector>
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<queue>
#include<limits.h>
using namespace std;
class Solution1 {
public:
int ladderLength(string start, string end, set<string> &dict)
{
if (start == end)
return 1;
int Res = INT_MAX;
vector<bool> bvec(dict.size(), false);
vector< vector<string> > res;
vector<string> tmp;
tmp.push_back(start);
Find(start, end, dict, bvec, res, tmp);
for(int i=0;i<res.size();i++)
{
Res = Res < res[i].size()?Res:res[i].size();
//for (int j=0;j<res[i].size();j++)
//cout<<res[i][j]<< " ";
//cout<<endl;
}
return Res;
}
void Find(string cur, string end, set<string> &dict, vector<bool> &bvec, vector< vector<string> > &res, vector<string> &tmp)
{
if (IfOneDiff(cur,end))
{
tmp.push_back(end);
res.push_back(tmp);
tmp.pop_back();
}
set<string> ::iterator iter = dict.begin();
for (int i=0;i<dict.size();i++,iter++)
{
if (!bvec[i] && IfOneDiff(cur, *iter))
{
tmp.push_back(*iter);
bvec[i] = true;
Find(*iter, end, dict, bvec, res, tmp);
bvec[i] = false;
tmp.pop_back();
}
}
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
class Solution2 {
public:
int ladderLength(string start, string end, set<string> &dict)
{
if (start == end)
return 1;
int res = INT_MAX;
vector<bool> bvec(dict.size(), false);
vector<string> tmp;
tmp.push_back(start);
Find(start, end, dict, bvec, res, tmp);
return res;
}
void Find(string cur, string end, set<string> &dict, vector<bool> &bvec, int &res, vector<string> &tmp)
{
if (IfOneDiff(cur,end))
{
tmp.push_back(end);
res = res<tmp.size()?res:tmp.size();
tmp.pop_back();
return;
}
set<string> ::iterator iter = dict.begin();
for (int i=0;i<dict.size();i++,iter++)
{
if (!bvec[i] && IfOneDiff(cur, *iter))
{
tmp.push_back(*iter);
bvec[i] = true;
Find(*iter, end, dict, bvec, res, tmp);
bvec[i] = false;
tmp.pop_back();
}
}
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
class Solution {
public:
int ladderLength(string start, string end, set<string> &dict)
{
queue<pair<string, int> > que;
que.push(make_pair(start, 1));
dict.insert(end);
set<string> ::iterator it = dict.find(start);
if (it != dict.end())
dict.erase(it);
while(!que.empty())
{
pair<string, int> tmp = que.front();
int size = dict.size();
que.pop();
set<string> ::iterator iter = dict.begin();
if (tmp.first == end)
return tmp.second;
for (int i=0;i<size;i++)
{
if (IfOneDiff(tmp.first, *iter))
{
que.push(make_pair(*iter, tmp.second+1));
dict.erase(iter++);
}
else
iter++;
}
}
return 0;
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
class Solution3 {
public:
int ladderLength(string start, string end, set<string> &dict)
{
queue<pair<string, int> > que;
que.push(make_pair(start, 1));
dict.insert(end);
set<string> ::iterator it = dict.find(start);//去掉start 不去也行
if (it != dict.end())
dict.erase(it);
while(!que.empty())
{
pair<string, int> tmp = que.front();
int size = dict.size();
que.pop();
set<string> ::iterator iter = dict.begin();
if (tmp.first == end)
return tmp.second;
while (dict.end() != iter)
{
if (IfOneDiff(tmp.first, *iter))
{
que.push(make_pair(*iter, tmp.second+1));
dict.erase(iter++);//这里一定要去掉 不然时间太久不通过
}
else
iter++;
}
}
return 0;
}
bool IfOneDiff(string s1, string s2)
{
if (s2.size() != s2.size())
return false;
int size = 0;
for (int i=0;i<s1.size();i++)
{
if(s1[i] != s2[i])
if (++size > 1)
return false;
}
return size == 1;
}
};
//"a","c",["a","b","c"]
int main()
{
Solution3 s;
set<string> dict;
//["hot","dot","dog","lot","log"]
dict.insert("hot");
dict.insert("dot");
dict.insert("dog");
dict.insert("lot");
dict.insert("log");
cout<<s.ladderLength("hit", "cog", dict)<<endl;
}

本文探讨了从一个单词到另一个单词的最短转换序列问题,利用字典作为辅助,并详细介绍了使用深度优先搜索(DFS)和广度优先搜索(BFS)两种算法解决该问题的方法。
2821

被折叠的 条评论
为什么被折叠?



