点击关注公众号,干货第一时间送达

这题是一道华为OD笔试题目,
具体什么时间点考的,
小编不确定哈
小编不是面试官,也不是出题人,
只是个解题人哈
抛开诸位对华为OD的看法,
只看此题,
你能解答出来吗?
在力扣上可以找到原题:
https://leetcode.cn/problems/word-ladder/solutions/276923/yan-du-you-xian-bian-li-shuang-xiang-yan-du-you-2/
一、屏幕前的吴彦祖和刘亦菲们,请听题

举个例子:

题意都明白否?
其实就是个最短转换路径问题,
也就是图问题。
最短转换路径问题的解法有哪些?
广度优先遍历 & 深度优先遍历
二、解题
(插句题外话哈,互联网企业的笔试题目,图的问题基本是必考的。三道笔试题,至少有一题是图相关的,所以诸君平时多练练这些题目哈,有备无患)
明确了是图,咱们先在草稿纸上画个简单的图:

接下来就是求解,
beginWord -> endWord 的最短路径了。
题目中设定的是每个单词中的每个字符可以替换一次,
也就是说:

如上图,单词hit的每个字符都要尝试 a-z 的单个替换。
当然,需要判断替换形成的新字符串,是否在给定的 wordList 中,即是有效的:

如果有效,则路径+1,
最终新字符串正好等于 endWord 即可。
因为这个图是无向,为了防止回头,走过的路我们记录下来,
就是新的单词都记录下来,下次不再记录了:

聪明的小伙伴肯定发现了,
这题的的最短路径求解,
就是 dijstra 算法:

看了这么多讲解,
最重要的还是要code,
看看代码。
完整代码:
public class CodingDemo_03 {
/**
* 单词接龙
* @param beginWord
* @param endWord
* @param wordList
* @return
*/
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
//1,将给定单词列表转换为set,方便后续查找
Set<String> wordSet = new HashSet<>(wordList);
//因为题目要求 beginword 不在给定单词列表,这里我们删除可能存在的情况
wordSet.remove(beginWord);
//如果给定单词列表不包含 endword,肯定无法转换
if (!wordSet.contains(endWord)){
return 0;
}
//2,采用广度优先遍历,判断哪些可以满足一个字符替换
//并同时记录哪些单词被访问过
Deque<String> queue = new LinkedList<>();
queue.addLast(beginWord);
Set<String> visited = new HashSet<>();
//开始遍历
int step = 1; //记录转换次数
while (!queue.isEmpty()){
int curSize = queue.size();
//广度遍历
for (int i = 0; i < curSize; i++) {
//弹出当前单词
String curWord = queue.pollFirst();
//判断当前单词,是否可以只变化一个字符,即可转换为 endWord
//如果可以,则直接返回记录步数 step
if (changeOneWordToEnd(wordSet, queue, visited,endWord, curWord)){
return step + 1;
}
}
step++;//转换步数增加
}
return 0;
}
private boolean changeOneWordToEnd(Set<String> wordSet, Deque<String> queue,
Set<String> visited, String endWord, String curWord){
//1,因为要判断当前单词curWord,
//只变化一个字符
//所以先将字符串转换字符数组,方便字符替换
final char[] ch = curWord.toCharArray();
//2,尝试对每个字符进行 a-z 替换
for (int i = 0; i < ch.length; i++) {
//2.1 先把老字符记录下来
char odd = ch[i];
//2.2 尝试26种字符替换
for (char j = 'a'; j <= 'z'; j++) {
if (j == odd){
continue;
}
//2.3 替换
ch[i] = j;
//2.4 替换后的先单词
String newWord = String.valueOf(ch);
//2.5 判断是否存在
if (wordSet.contains(newWord)){
if (newWord.equals(endWord)){
return true;
}
//如果之前没有被访问,则加入到队列,供下次遍历判断
//并标记为已经访问
if (!visited.contains(newWord)){
queue.offerLast(newWord);
visited.add(newWord);
}
}
}
//还原
ch[i] = odd;
}
return false;
}
}
去力扣试试:


文章转载自皮皮克克,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




