题目链接 : https://leetcode-cn.com/problems/word-ladder-ii/

题目描述:

给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:

  1. 每次转换只能改变一个字母。
  2. 转换过程中的中间单词必须是字典中的单词。

说明:

  • 如果不存在这样的转换序列,返回一个空列表。
  • 所有单词具有相同的长度。
  • 所有单词只由小写字母组成。
  • 字典中不存在重复的单词。
  • 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。

示例:

示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"] 输出:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]

示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"] 输出: [] 解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。

思路:

这道题 BFS + DFS

BFS求从beginWordendWord最短距离,经过哪些单词, 用字典记录离beginWord的距离;

DFS求从beginWordendWord有哪些路径

Java 代码写的我怀疑人生, 可以帮我简化吗?

代码:

class Solution:
def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
from collections import defaultdict
wordList = set(wordList)
res = []
# 记录单词下一步能转到的单词
next_word_dict = defaultdict(list)
# 记录到beginWord距离
distance = {}
distance[beginWord] = 0 # 找一个单词能转到的单词
def next_word(word):
ans = []
for i in range(len(word)):
for j in range(97, 123):
tmp = word[:i] + chr(j) + word[i + 1:]
if tmp != word and tmp in wordList:
ans.append(tmp)
return ans
# 求到beginWord的距离
def bfs():
cur = [beginWord]
step = 0
flag = False
while cur:
step += 1
next_time = []
for word in cur:
for nw in next_word(word):
next_word_dict[word].append(nw)
if nw == endWord:
flag = True
if nw not in distance:
distance[nw] = step
next_time.append(nw)
if flag:
break
cur = next_time
# 遍历所有从beginWord到endWord的路径
def dfs(tmp, step):
if tmp[-1] == endWord:
res.append(tmp)
return
for word in next_word_dict[tmp[-1]]:
if distance[word] == step + 1:
dfs(tmp + [word], step + 1) bfs()
dfs([beginWord], 0)
return res

java

class Solution {
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
Set<String> wordList_set = new HashSet<>(wordList);
List<List<String>> res = new ArrayList<>();
Map<String, ArrayList<String>> next_word_map = new HashMap<>();
Map<String, Integer> distance = new HashMap<>(); bfs(beginWord, endWord, next_word_map, distance, wordList_set);
dfs(beginWord, endWord, next_word_map, 0, res, new ArrayList<String>(Arrays.asList(beginWord)), distance);
return res;
} private void dfs(String beginWord, String endWord, Map<String, ArrayList<String>> next_word_map, int step, List<List<String>> res, ArrayList<String> tmp, Map<String, Integer> distance) { if (tmp.get(tmp.size() - 1).equals(endWord)) res.add(new ArrayList<>(tmp));
for (String word : next_word_map.get(tmp.get(tmp.size() - 1))) {
tmp.add(word);
if (distance.get(word) == step + 1) dfs(word, endWord, next_word_map, step + 1, res, tmp, distance);
tmp.remove(tmp.size() - 1);
}
} private void bfs(String beginWord, String endWord, Map<String, ArrayList<String>> next_word_map, Map<String, Integer> distance, Set<String> wordList_set) {
for (String s : wordList_set) next_word_map.put(s, new ArrayList<String>());
next_word_map.put(beginWord, new ArrayList<>());
Queue<String> queue = new LinkedList<>();
queue.offer(beginWord);
distance.put(beginWord, 0);
boolean flag = false;
int step = 0;
while (!queue.isEmpty()) {
step++;
int n = queue.size();
for (int i = 0; i < n; i++) {
String word = queue.poll();
for (String nw : next_word(word, wordList_set)
) {
next_word_map.getOrDefault(word, new ArrayList<>()).add(nw);
if (nw.equals(endWord)) flag = true;
if (!distance.containsKey(nw)){
distance.put(nw, step);
queue.offer(nw);
} }
}
if (flag) break;
}
} private ArrayList<String> next_word(String word, Set<String> wordList_set) {
ArrayList<String> ans = new ArrayList<>(); for (int i = 0; i < word.length(); i++) {
char[] chars = word.toCharArray();
for (char ch = 'a'; ch <= 'z'; ch++) {
chars[i] = ch;
String tmp = new String(chars);
if (!tmp.equals(word) && wordList_set.contains(tmp)) ans.add(tmp);
}
}
return ans;
}
}

[LeetCode] 126. 单词接龙 II的更多相关文章

  1. Java实现 LeetCode 126 单词接龙 II

    126. 单词接龙 II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: ...

  2. Leetcode 126.单词接龙II

    单词接龙II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: 每次转换只能 ...

  3. 126. 单词接龙 II

    题目: 链接:https://leetcode-cn.com/problems/word-ladder-ii/ 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出 ...

  4. LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)

    题目: Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transfo ...

  5. Java实现 LeetCode 127 单词接龙

    127. 单词接龙 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字 ...

  6. [Swift]LeetCode126. 单词接龙 II | Word Ladder II

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  7. lintcode 单词接龙II

    题意 给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列 比如: 1.每次只能改变一个字母. 2.变换过程中的中间单词必须在字典中出现. 注意事项 所有单词具有相 ...

  8. leetcode 127 单词接龙

    给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字母. 转换过程中的中 ...

  9. leetcode 137单词接龙

    直接层序遍历,结果有部分测试样例超时: class Solution { public: int ladderLength(string beginWord, string endWord, vect ...

随机推荐

  1. vertica,greenplumr容器安装

    一,vertica 来源: https://github.com/sumitchawla/docker-vertica 使用方法: # To run without a persistent data ...

  2. SQL高级教程-TOP 子句

    TOP 子句 TOP 子句用于规定要返回的记录的数目. 对于拥有数千条记录的大型表来说,TOP 子句是非常有用的. 注释:并非所有的数据库系统都支持 TOP 子句. SQL Server 的语法: S ...

  3. BZOJ 4653: [Noi2016]区间 双指针 + 线段树

    只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...

  4. UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

    题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  5. CodeForces 1100F Ivan and Burgers

    CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags da ...

  6. java开发需掌握技能2

    1.了解Dubbo+Zookeeper面向服务SOA架构.SpringCloud+Eureka微服务架构.ActiveMQ消息通讯模式.RocketMQ分布式消息.Zookeeper集群.Redis缓 ...

  7. 官方转译:截止2018-12-10,chromedriver与chrome对应关系表

    谷歌驱动下载地址: http://npm.taobao.org/mirrors/chromedriver/ http://chromedriver.storage.googleapis.com/ind ...

  8. 在MyEclipse安装Spket插件,用于jQuery代码提示

    Spket插件下载: https://pan.baidu.com/s/1sjz24NF 解压文件,然后将解压后的文件全部复制到MyEclipse安装目录下的dropins包中,重启MyEclipse. ...

  9. 关于kafka在windows上的安装、运行

    一.安装kafka    下载地址:http://kafka.apache.org/downloads 要下载Binary downloads这个类型,不要下载源文件,这种方便使用.下载后,解压放在D ...

  10. [ git ] eclipse如何与git 配合工作。

    原文链接http://blog.csdn.NET/yangzhihello/article/details/11003941 呵呵,看看这个吧.先去安装eclipse.然后在现在 egit,应该可以从 ...