题目:
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence fromstart 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 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:dijkstra算法,可以额外建立距离矩阵时间和空间开销太大。 思路2:BFS
代码:
思路1:
class Solution {
public:
string start;
string end;
unordered_set<string> dict;
int ladderLength(string start, string end, unordered_set<string> &dict) {
this->start = start;
this->end = end;
this->dict = dict;
int **dist = new int*[dict.size()+2];
for(int k=0;k<dict.size()+2;k++)
{
dist[k]=new int[dict.size()+2];
}
int len=dict.size()+2;
for(int i=0;i<len;i++)
{
for(int j=i;j<len;j++)
{
if(i==j)
{
dist[i][j]=INT_MAX;
}
else
{
dist[i][j]=dist[j][i]=getDist(getString(i),getString(j));
}
}
}
int* minDist=new int[len];
bool* visited = new bool[len];
for(int i=0;i<len;i++)
{
minDist[i]=dist[0][i];
visited[i]=false;
}
while(minDist[dict.size()]==INT_MAX)
{
int min = INT_MAX;
int minD = INT_MAX;
for(int i=1;i<len;i++)
{
if(!visited[i]&&minDist[i]<minD)
{
minD = minDist[i];
min = i;
}
}
if(min==INT_MAX)
{
break;
}
else
{
visited[min]=true;
for(int i=1;i<len;i++)
{
if(minDist[i]>minDist[min]+dist[min][i])
{
minDist[i]=minDist[min]+dist[min][i];
}
}
}
}
return minDist[dict.size()]==INT_MAX?0:minDist[dict.size()];
}
int getDist(string s1, string s2)
{
int d=0;
for(int i;i<s1.size();i++)
{
if(s1[i]!=s2[i])
{
d++;
}
}
return d==1?1:INT_MAX;
}
string getString(int k)
{
if(k==0)
{
return start;
}
else if(k==dict.size()+1)
{
return end;
}
else
{
auto it = dict.begin();
while(k>1)
{
it++;
k--;
}
return *it;
}
}
};
思路2:
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
if(start==end)
{
return 1;
}
queue<string> nodes;
queue<int> depth;
nodes.push(start);
depth.push(1);
findItem(start,dict);
while(nodes.size()>0)
{
string cur = nodes.front();
nodes.pop();
int d = depth.front();
depth.pop();
for(int i=0;i<cur.size();i++)
{
for(int j=0;j<26;j++)
{
if(cur[i]!='a'+j)
{
string tmp = cur;
tmp[i] = 'a'+j;
if(tmp==end)
{
return d+1;
}
if(findItem(tmp,dict))
{
nodes.push(tmp);
depth.push(d+1);
}
}
}
}
}
return 0;
}
bool findItem(string s, unordered_set<string> &dict)
{
unordered_set<string>::const_iterator p = dict.find(s);
if(p!=dict.end())
{
dict.erase(p);
return true;
}
else
{
return false;
}
}
};