Word Ladder
Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformation sequence from beginWord to endWord, 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.
解题思路:
第一的想法是用一个图来记录相邻关系,然后将问题转化成图的最短路径问题。
class Solution {
public:
int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
if(beginWord == endWord){
return 1;
}
if(isNeibor(beginWord, endWord)){
return 2;
}
if(wordDict.find(beginWord)==wordDict.end()){
wordDict.insert(beginWord);
}
if(wordDict.find(endWord)==wordDict.end()){
wordDict.insert(endWord);
}
//将set转化成vector
vector<string> wordVect;
for(unordered_set<string>::iterator it = wordDict.begin(); it!=wordDict.end(); it++){
wordVect.push_back(*it);
}
int len = wordVect.size();
vector<vector<int>> graph(len, vector<int>()); //邻接表存储图
int beginIndex = -1;
int endIndex = -1;
for(int i=0; i<len; i++){
if(beginWord == wordVect[i]){
beginIndex = i;
}
if(endWord == wordVect[i]){
endIndex = i;
}
for(int j=i+1; j<len; j++){
if(isNeibor(wordVect[i], wordVect[j])){
graph[i].push_back(j);
graph[j].push_back(i);
}
}
}
vector<int> pre(len, -1); //某个节点的前驱节点
pre[beginIndex] = beginIndex;
queue<int> q({beginIndex}); //广度优先法
bool flag = false; //是否已经找到了路径
while(!q.empty()){
int c = q.front();
q.pop();
for(int i=0; i<graph[c].size(); i++){
if(pre[graph[c][i]]<0){
pre[graph[c][i]] = c;
q.push(graph[c][i]);
if(graph[c][i]==endIndex){
flag = true;
break;
}
}
}
if(flag){
break;
}
}
if(!flag){
return 0;
}
int result = 1;
int c = endIndex;
while(pre[c]!=c){
result++;
c = pre[c];
}
return result;
}
bool isNeibor(const string& str1, const string& str2){
int len = str1.length();
if(len!=str2.length()){
return false;
}
int c = 0;
for(int i=0; i<len; i++){
if(str1[i]!=str2[i]){
c++;
}
}
return c==1;
}
};