赞
踩
字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:
给你两个单词 beginWord 和 endWord 和一个字典 wordList,找到从 beginWord 到 endWord 的 最短转换序列 中的单词数目 。如果不存在这样的转换序列,返回 0。
示例 1:
输入:
beginWord = “hit”,
endWord = “cog”,
wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:5
解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。
示例 2:
输入:
beginWord = “hit”,
endWord = “cog”,
wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出:0
解释:endWord “cog” 不在字典中,所以无法进行转换。
提示:
1 <= beginWord.length <= 10
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord、endWord 和 wordList[i] 由小写英文字母组成
beginWord != endWord
wordList 中的所有字符串 互不相同
以第一个示例为例进行分析:
如上图所示,可将该问题抽象为一个图,那么要找到 beginWord 到 endWord 的最短转换序列的单子数量,只需要进行一次BFS检索即可。
按照上图的规则进行广搜遍历即可:
最初代码如下:
/** * 解题思路: * 使用level记录当前遍历到了第几层 * 用map标记上一层使用到的单词,在本层中不可重复使用 * 写一个函数来检查两个单词是不是只差一个字符,返回一个boolean * * @param beginWord * @param endWord * @param wordList * @return */ public int ladderLength(String beginWord, String endWord, List<String> wordList) { // bfs的深度 int level = 0; // 检查endWord是不是包含在wordList中 if (!wordList.contains(endWord)) { return 0; } // 标记单词是不是已经使用过 Set<String> map = new HashSet<>(); Set<String> tmpMap = new HashSet<>(); // 定义一个Queue来实现bfs Queue<String> queue = new ArrayDeque<>(); queue.add(beginWord); while (!queue.isEmpty()) { /** 从前向后 */ int count = queue.size(); level++; // 将上一层bfs使用过的单词,在该层统一进行标记 map.addAll(tmpMap); tmpMap.clear(); while (--count >= 0) { // 拿出queue中的元素,并在list中查找与其仅有一个字符不同的单词 String key = queue.remove(); // 将key临时记录,并在当前循环结束之后放入map中记录,之后不再访问 tmpMap.add(key); // 便利整个wordList,找到key可以通过一次变换得到的单词,如果该单词未被访问过,将其放入队列中 for (String s : wordList) { // 比较key和list中未曾访问过的某个元素是不是仅有一个字符不同 if (!map.contains(s) && checkDiff(key, s)) { queue.add(s); // 当前元素s等于endWord的时候,返回即可 if (s.equals(endWord)) { return level + 1; } } } } } return 0; } /** * 检查key和s是不是只有一个字符不相同 * @param key * @param str * @return 满足条件则返回true,否则返回false */ private boolean checkDiff(String key, String str) { if (key == null || str == null) { return false; } int count = 0; int keyLen = key.length(); int strLen = str.length(); if (keyLen != strLen) { return false; } for (int i = 0; i < keyLen; i++) { if (key.charAt(i) != str.charAt(i)) { count++; if (count > 1) { return false; } } } return count == 1; }
在leetcode提交后,超时
该方法未进行任何优化,时间复杂度极高。可以进行初步优化:
- 检索key通过变化一个字符可变成的单词的时候,在全部wordList中检索,此处可以通过构建一个map存放key可以转化成的单词列表,比如用 Map<String, Set< String>> 来存储。
优化后的代码如下:
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
// bfs的深度
int level = 0;
wordList.add(beginWord);
// 检查endWord是不是包含在wordList中
if (!wordList.contains(endWord)) {
<
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。