Word Ladder
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.
分析:
1. 一开始觉得,hit 变到 cog,肯定是每次变化一个单词,距离len+1。只要判断每一种变化的可能是否在dict中即可。 忽略了字典中很多词可以作为中间状态,例如dog就与hit没有任何字母相同。
2. Google之,BST,广度优先遍历。start到end可以看做是 点到点的一条路径,而每变化一个单词可以看做是路径+1。
如例子中,hit作为第一层,第二层则是((a-z)it ∩ dict)∪(h(a-z)t ∩ dict) ∪(hi(a-z) ∩ dict)然后除去hit本身。注意end(即cog不需要在词典中)依次往下推,如果发现了end,则直接返回当前的distance即可。因为是层序遍历,所以当前路径保证是最小的。
注意:
1. 层序遍历用queue,每层过渡节点push到队列中后,对应的dict中的单词要删掉。因为不删掉会进入死循环,如hit -> hot->lot -> hot 每次改变一个单词,会变成它的前一个节点。
2. 每层的分界线,用""
代码:
class Solution {
public:
int ladderLength(string start, string end, unordered_set<string> &dict) {//BFS 最短路径问题
if(start==end) return 0;
int len=start.size();
queue<string> qu;
qu.push(start);
qu.push("");//标记每一层
int distance=1;
while(qu.size()>1 && dict.size()>0){//每层循环
//distance++;
while(qu.front()!="" && dict.size()>0){//每层内一个个元素的循环
string tmp=qu.front();
qu.pop();
for(int i=0;i<len;i++){
string pusht=tmp;
for(char t='a';t<='z';t++){//a-z依次试探,看是否在dict中
if(pusht[i]==t) continue;//tmp本身
pusht[i]=t;
if(pusht==end) return distance+1;//找到了 便是最短的 层序遍历
unordered_set<string>::const_iterator it=dict.find(pusht);
if(it!=dict.end()){//字典中有这个单词
qu.push(pusht);
dict.erase(it);//删除字典中对应的值
}
}//for t
}//for i
}//while
qu.pop();//删除""
if(qu.empty()) return 0;
else distance++;
qu.push("");
} //层while
return 0;
}
};

690

被折叠的 条评论
为什么被折叠?



