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.
此题目适合用BFS,因为BFS能很快获得最小次数而提前终止,DFS则不能
//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();
}
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
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;
}
};
测试
#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();
}
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;
}
};
//"a","c",["a","b","c"]
int main()
{
Solution s;
set<string> dict;
//["hot","dot","dog","lot","log"]
//dict.insert("a");
dict.insert("b");
dict.insert("c");
//dict.insert("lot");
//dict.insert("log");
cout<<s.ladderLength("a", "c", dict)<<endl;
}