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
.
思路:
找两点之间的最小距离,感觉只能用图,构建图的邻接矩阵,然后folyd 果断的超时了.....
int ladderLength1(string start, string end, unordered_set<string> &dict) { if(start == end) return 1; int vexnum = dict.size() + 2; if(dict.find(start) != dict.end()) vexnum--; if(dict.find(end) != dict.end()) vexnum--; vector<string> s(vexnum); //记录graph中每行代表的单词 vector<vector<int>> graph(vexnum, vector<int>(vexnum, vexnum + 1)); //邻接矩阵 s[0] = start; s.back() = end; int i = 1; unordered_set<string>::iterator it; for(it = dict.begin(); it != dict.end(); it++) { if(*it != start && *it != end) s[i++] = (*it); } //记录有哪些单词可以通过一次变化相互转换 for(i = 0; i < s.size(); i++) { string temp = s[i]; for(int j = 0; j < start.size(); j++) { for(char c = 'a'; c <= 'z'; c++) { temp[j] = c; if(dict.find(temp) != dict.end()) { int edge = find(s.begin(), s.end(), temp) - s.begin(); if(edge == i) { graph[i][edge] = 0; graph[edge][i] = 0; } else { graph[i][edge] = 1; graph[edge][i] = 1; } } } } } for(int k = 0; k < graph.size(); k++) { for(int i = 0; i < graph.size(); i++) { for(int j = 0; j < graph.size(); j++) { if(graph[i][j] > graph[i][k] + graph[k][j]) { graph[i][j] = graph[i][k] + graph[k][j]; } } } } return (graph[0][vexnum - 1] == vexnum + 1) ? 0 : graph[0][vexnum - 1] + 1; }
来看大神的BFS算法,用dis记录每个点到start的距离。队列里开始只有start, 然后每次遇到新转化成的单词就进队列,更新距离。判断能否转化时用字符长度和26个字母,而不是对字典遍历,因为字典中单词的数量可能远大于26个。
int ladderLength(string start, string end, unordered_set<string> &dict) { unordered_map<string, int> dis; queue<string> q; dis[start] = 1; q.push(start); while(!q.empty()) { string word = q.front(); q.pop(); for(int i = 0; i < start.size(); i++) { string temp = word; for(char c = 'a'; c <= 'z'; c++) { temp[i] = c; if(dict.count(temp) > 0 && dis.count(temp) == 0) { dis[temp] = dis[word] + 1; q.push(temp); } } } } if(dis.count(end) == 0) return 0; return dis[end]; }