题目链接 : 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. 如何使用dump文件进行调试

    转载[文尾出处链接] 1 简介第一次遇到程序崩溃的问题,之前为单位开发了一个插件程序,在本机运行没有出现问题,但把生成的可执行文件拷贝到服务器上一运行程序,刚进入插件代码,插件服务就崩溃了,当时被这个 ...

  2. bing 精美壁纸获取方式

    右键检查 打开就行了

  3. Linux培训教程 linux系统下分割大文件的方法

    在linux中分割大文件,比如一个5gb日志文件,需要把它分成多个小文件,分割后以利于普通的文本编辑器读取. 有时,需要传输20gb的大文件,Linux培训 教程件到另一台服务器,也需要把它分割成多个 ...

  4. UVA 12299 线段树 ( 单点跟新 , 区间查询)

    题目链接:题意:在传统的RMQ的基础上加上一个操作:shift(i1,i2,i3...ik),表示将这些元素,依次向左移动一位(训练指南247页) #include <iostream> ...

  5. luogu P1352 没有上司的舞会 x

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

  6. python常用类库总结

    个人学习总结,如有错误,请留言指正. 类库归类总结 类库关系

  7. 将DVD.iso 挂载到虚拟机

    将DVD.iso挂载到虚机之后,默认设备名是/dev/sr0 挂载DVD.iso文件到/mnt. 操作: mount /dev/sr0 /mnt 查看: ll /mnt

  8. Hbase数据备份&&容灾方案

    Hbase数据备份&&容灾方案 标签(空格分隔): Hbase 一.Distcp 在使用distcp命令copy hdfs文件的方式实现备份时,需要禁用备份表确保copy时该表没有数据 ...

  9. Long类源码浅析

    1.Long类和Integer相类似,都是基本类型的包装类,类中的方法大部分都是类似的: 关于Integer类的浅析可以参看:Integer类源码浅析 2.这里主要介绍一下LongCache类,该缓存 ...

  10. 修改docker下mysql配置

    1.在/home/smile/docker/mysql/config/目录下增加一个文件 my.cnf # Copyright (c) , Oracle and/or its affiliates. ...