[LeetCode] 126. 单词接龙 II
题目链接 : https://leetcode-cn.com/problems/word-ladder-ii/
题目描述:
给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:
- 每次转换只能改变一个字母。
- 转换过程中的中间单词必须是字典中的单词。
说明:
- 如果不存在这样的转换序列,返回一个空列表。
- 所有单词具有相同的长度。
- 所有单词只由小写字母组成。
- 字典中不存在重复的单词。
- 你可以假设 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求从beginWord 到endWord最短距离,经过哪些单词, 用字典记录离beginWord的距离;
用DFS求从beginWord 到endWord有哪些路径
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的更多相关文章
- Java实现 LeetCode 126 单词接龙 II
126. 单词接龙 II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: ...
- Leetcode 126.单词接龙II
单词接龙II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: 每次转换只能 ...
- 126. 单词接龙 II
题目: 链接:https://leetcode-cn.com/problems/word-ladder-ii/ 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出 ...
- LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)
题目: Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transfo ...
- Java实现 LeetCode 127 单词接龙
127. 单词接龙 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字 ...
- [Swift]LeetCode126. 单词接龙 II | Word Ladder II
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- lintcode 单词接龙II
题意 给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列 比如: 1.每次只能改变一个字母. 2.变换过程中的中间单词必须在字典中出现. 注意事项 所有单词具有相 ...
- leetcode 127 单词接龙
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字母. 转换过程中的中 ...
- leetcode 137单词接龙
直接层序遍历,结果有部分测试样例超时: class Solution { public: int ladderLength(string beginWord, string endWord, vect ...
随机推荐
- vertica,greenplumr容器安装
一,vertica 来源: https://github.com/sumitchawla/docker-vertica 使用方法: # To run without a persistent data ...
- SQL高级教程-TOP 子句
TOP 子句 TOP 子句用于规定要返回的记录的数目. 对于拥有数千条记录的大型表来说,TOP 子句是非常有用的. 注释:并非所有的数据库系统都支持 TOP 子句. SQL Server 的语法: S ...
- BZOJ 4653: [Noi2016]区间 双指针 + 线段树
只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- CodeForces 1100F Ivan and Burgers
CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags da ...
- java开发需掌握技能2
1.了解Dubbo+Zookeeper面向服务SOA架构.SpringCloud+Eureka微服务架构.ActiveMQ消息通讯模式.RocketMQ分布式消息.Zookeeper集群.Redis缓 ...
- 官方转译:截止2018-12-10,chromedriver与chrome对应关系表
谷歌驱动下载地址: http://npm.taobao.org/mirrors/chromedriver/ http://chromedriver.storage.googleapis.com/ind ...
- 在MyEclipse安装Spket插件,用于jQuery代码提示
Spket插件下载: https://pan.baidu.com/s/1sjz24NF 解压文件,然后将解压后的文件全部复制到MyEclipse安装目录下的dropins包中,重启MyEclipse. ...
- 关于kafka在windows上的安装、运行
一.安装kafka 下载地址:http://kafka.apache.org/downloads 要下载Binary downloads这个类型,不要下载源文件,这种方便使用.下载后,解压放在D ...
- [ git ] eclipse如何与git 配合工作。
原文链接http://blog.csdn.NET/yangzhihello/article/details/11003941 呵呵,看看这个吧.先去安装eclipse.然后在现在 egit,应该可以从 ...