题目链接 : 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. API网关原理

    1.API网关介绍 API网关是一个服务器,是系统的唯一入口.从面向对象设计的角度看,它与外观模式类似.API网关封装了系统内部架构,为每个客户端提供一个定制的API.它可能还具有其它职责,如身份验证 ...

  2. 查看SSL证书的别名

    1.把java目录下的keytool拷贝到证书目录下:2.进入证书目录,然后输入命令keytool -list -v -keystore file.jks -storepass password,发现 ...

  3. matlab中画三维图形

    这里主要讲述两个方法用matlab画三维图形: 1.mesh函数 先看一个简单的例子: x = ::; y = ::; [X, Y] = meshgrid(x, y); Z = zeros(,); Z ...

  4. 运行roslaunch启动节点报错找不到节点

    报错信息: ERROR: cannot launch node of type [${package_name}/${package_name}_node]: can't locate node [$ ...

  5. (69)Python异常处理与断言

    http://blog.csdn.net/pipisorry/article/details/21841883 断言 断言是一句必须等价于布尔真的判定;此外,发生异常也意味着表达式为假.这些工作类似于 ...

  6. html初体验#2

    碎碎念 关于布局 css布局:横向.纵向 2019年新进展:css grid git bash 上安装 http server 目的在于不使用 file:// 打开自己写的文件,使用 http:// ...

  7. SpringMVC - <mvc:default-servlet-handler/> 导致 Controller失效

    原文地址:http://blog.csdn.net/j080624/article/details/66969987

  8. socket基本概念

    1.socket 是什么? 在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其 ...

  9. Oracle JET 单页面应用程序Router 使用(上)

    单页面应用程序:使用一个进加载一次的网页,如果页面由于用户的交互而改变,则仅绘制更改的页面部分. 要创建单页面应用程序需要使用 oj.Router 的虚拟导航来支持,ojModule 用来响应页面的重 ...

  10. 用ps 查看线程状态

    ps -eLo pid,tid,class,rtprio,ni,pri,psr,pcpu,pmem,stat,wchan:30,comm 线程相关选项: THREAD DISPLAY H Show t ...