题目
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.
思路一
递归 + 遍历 + 剪枝
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
int min = INT_MAX;
myladder(start,end,dict,1,min);
if(min==INT_MAX)
return 0;
return min;
}
void myladder(string start, string &end, unordered_set<string> &dict, int cur, int &min) {
if(start==end) {
if(cur<min)
min = cur;
return ;
}
if(cur>min) return ;
int len = start.length();
for(int i=0; i<len; i++) {
char ch = start[i];
dict.erase(start);
for(int j='a'; j<='z'; j++) {
if(ch!=j) {
start[i] = j;
unordered_set<string>::iterator index = dict.find(start);
if(index!=dict.end()){
dict.erase(start);
myladder(start,end,dict,cur+1,min);
dict.insert(start);
}
}
}
start[i] = ch;
dict.insert(start);
}
}
};
小数据可以通过,大数据超时。
思路二
用队列 Queue 迭代 BFS
(1)用 unordered_map<string, bool> visited 来标记是否已经访问过(思路一是通过删除和插入来实现的);
(2)先将 start 压入队列 myqueue 中;
(3)得到所有 start 能够转变的且在字典中的 word ,如果有 end ,则返回长度;否则全部压入另一队列 nextqueue 中;
(4)将 myqueue = nextqueue ,然后将 myqueue 中所有的 word 置为start ,进入步骤(3);
(5)否则返回 0, 即没有找到转化。
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
if(dict.empty()) return 0;
int strLen = (*(dict.begin())).size();
if(start.size()!=end.size() || start.size() != strLen) return 0;
if(start==end) return 1;
int shortestLen=1;
unordered_map<string, bool> visited;
queue<string> myqueue;
myqueue.push(start);
visited[start] = true;
while(!myqueue.empty()) {
shortestLen++;
queue<string> nextqueue;
while(!myqueue.empty()) {
start = myqueue.front();
myqueue.pop();
int len = start.length();
for(int i=0; i<len; i++) {
char ch = start[i];
for(int j='a'; j<='z'; j++) {
if(ch!=j) {
start[i] = j;
if(start==end)
return shortestLen;
if(dict.find(start)!=dict.end() && visited[start]==false){
nextqueue.push(start);
visited[start]=true;
}
}
}
start[i] = ch;
}
}
myqueue = nextqueue;
}
return 0;
}
};