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 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.
可以把这道题变成一个搜索单源最短路径的问题。利用DFS搜索
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
dict.erase(start);
dict.erase(end);
vector<string> words;
words.push_back(start);
words.insert(words.end(),dict.begin(),dict.end());
words.push_back(end);
int length=words.size();
int wordlength=start.size();
int count,min=INT_MAX;
bool *flag=new bool[length];
memset(flag,false,sizeof(bool)*length);
int (*graph)[10000]=new int[length][10000];
for(int i=0 ; i<length ; i++){
graph[i][i]=0;
for(int j=i+1 ; j<length ; j++){
count=0;
for(int k=0 ; k<wordlength ; k++){
if(words[i][k]!=words[j][k])
count++;
}
graph[i][j]=count;
graph[j][i]=count;
}
}//form the graph;
count=1;
flag[0]=true;
DFS(graph,0,length-1,flag,length,count,min);
return min==INT_MAX?0:min;
}
void DFS(int (*g)[10000], int i, const int j, bool *flag, int n, int& count, int& min){
if(i==j){
if(count<min)
min=count;
return;
}
for(int k=0 ; k<n ; k++){
if(g[i][k]==1 && !flag[k]){
flag[k]=true;
count++;
DFS(g,k,j,flag,n,count,min);
count--;
flag[k]=false;
}
}
}
};
但是过不了大数据,把DFS改成BFS试试。class Solution {
typedef pair<int,int> path;
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
dict.erase(start);
dict.erase(end);
vector<string> words;
words.push_back(start);
words.insert(words.end(),dict.begin(),dict.end());
words.push_back(end);
int length=words.size();
int wordlength=start.size();
int count,min=INT_MAX;
bool *flag=new bool[length];
memset(flag,false,sizeof(bool)*length);
int (*graph)[10000]=new int[length][10000];
for(int i=0 ; i<length ; i++){
graph[i][i]=0;
for(int j=i+1 ; j<length ; j++){
count=0;
for(int k=0 ; k<wordlength ; k++){
if(words[i][k]!=words[j][k])
count++;
}
graph[i][j]=count;
graph[j][i]=count;
}
}//form the graph;
queue<pair<int,int> > bfs;
bfs.push(make_pair(0,1));
while(!bfs.empty()){
path head=bfs.front();
flag[head.first]=true;
if(head.first==length-1)
return head.second;
for(int i=0 ; i<length ; i++){
if(graph[head.first][i]==1 && !flag[i])
bfs.push(path(i,head.second+1));
}
bfs.pop();
}
if(bfs.empty())
return 0;
}
};
我的这种先弄一个二维矩阵的方法好像不被允许,提示内存超了。主要的时间耗费在了前面矩阵赋值上面,那么就不要先计算出这种矩阵,边BFS边比较:
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
//BFS(because all edge is 1) to find the minimum path
//O(n*len*26)
queue<pair<string,int>> q;
unordered_set<string> visited;
q.push(make_pair(start, 1));
visited.insert(start);
while (!q.empty()) {
string curStr = q.front().first;
int curStep = q.front().second;
q.pop();
for (int i = 0; i < curStr.size(); ++i) {
string tmp = curStr;
for (int j = 0; j < 26; ++j) {
tmp[i] = j+'a';
if(tmp == end)
return curStep+1;
if(visited.find(tmp) == visited.end() && dict.find(tmp) != dict.end()) {
q.push(make_pair(tmp, curStep+1));
visited.insert(tmp);
}
}
}
}
return 0;
}
};