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 length5.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
给出了一个开始和一个结束,还有一个数组,每次变更一个字母,用数组中的词把首尾链接起来,吐出最短的长度。
思路:
这个题为什么可以使用广度优先遍历比深度好呢?举个例子:如果a->b并且a->c都是一步到达的,那么求最短就没有可能是a->b->c,所以可以使用广度优先遍历,并且把搜索出来的删掉,后面就完全不用管了。
所以就是使用bfs,找到能拼接起来的层数就可以结束了。
注意:这里用到的数据结构是队列
<?php
function onlyOneStr($word1, $word2) {
$noEqualNum = 0;
$num = strlen($word1);
for ($i = 0; $i < $num; $i ++) {
if ($word1[$i] !== $word2[$i]) {
$noEqualNum ++;
}
}
if ($noEqualNum == 1) {
return true;
} else {
return false;
}
}
function ladderLength($arrWord, $startWord, $stopWord) {
$arrNode = array();//这个数据结构应该用的是队列,先进先出
array_push($arrNode, $startWord);//第一层
$ret = 1;//层数
while (!empty($arrNode)) {
$num = count($arrNode);//第n层的节点个数
while ($num > 0) {//当这一层还有节点数的时候,继续获取节点
$node = array_shift($arrNode);
//判断现在是否可以连上结尾了
if (onlyOneStr($node, $stopWord)) {
print $node. $stopWord;
return $ret + 1;//层数再加上最后一层
}
$num --;
//获取这个节点的所有下层节点
foreach ($arrWord as $key => $item) {
//如果属于下层节点
if (onlyOneStr($item ,$node)) {
array_push($arrNode, $item);
unset($arrWord[$key]);
}
}
}
$ret ++;//开始到下一层的计算
}
return 0;
}
$arrWord = ["hot","dot","dog","lot","log"];
$startWord = "hit";
$stopWord = "cog";
$ret = ladderLength($arrWord, $startWord, $stopWord);
print $ret;