2020-03-19 13:10:35

问题描述:

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

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

说明:

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

示例 1:

  1. 输入:
  2. beginWord = "hit",
  3. endWord = "cog",
  4. wordList = ["hot","dot","dog","lot","log","cog"]
  5.  
  6. 输出:
  7. [
  8. ["hit","hot","dot","dog","cog"],
  9.   ["hit","hot","lot","log","cog"]
  10. ]

示例 2:

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

问题求解:

总体思路是先通过BFS搜索最小步数,并且记录BFS树,之后使用DFS得到路径。这里有个地方需要特别注意的是,在构建BFS树的时候,需要在某一层全部遍历结束后再把下一层的一起加入used中,否则会少掉一些上层到下层的边。

时间复杂度:O(n)

  1. List<List<String>> res = new ArrayList<>();
  2.  
  3. Set<String> dict = new HashSet<>();
  4. Map<String, Set<String>> graph = new HashMap<>();
  5.  
  6. public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
  7. for (String s : wordList) dict.add(s);
  8. if (!dict.contains(endWord)) return res;
  9. int step = bfs(beginWord, endWord);
  10. if (step == -1) return res;
  11. dfs(beginWord, endWord, new ArrayList<>(), step + 1);
  12. return res;
  13. }
  14.  
  15. private void dfs(String begin, String end, List<String> curr, int step) {
  16. curr.add(begin);
  17. if (curr.size() == step) {
  18. if (curr.get(step - 1).equals(end)) res.add(new ArrayList<>(curr));
  19. }
  20. else {
  21. for (String next : graph.get(begin)) {
  22. dfs(next, end, curr, step);
  23. }
  24. }
  25. curr.remove(curr.size() - 1);
  26. }
  27.  
  28. private int bfs(String begin, String end) {
  29. boolean flag = false;
  30. Queue<String> q = new LinkedList<>();
  31. Set<String> used = new HashSet<>();
  32. q.add(begin);
  33. used.add(begin);
  34. int step = 0;
  35. while (!q.isEmpty()) {
  36. if (flag) return step;
  37. int size = q.size();
  38. Set<String> layer_used = new HashSet<>();
  39. for (int k = 0; k < size; k++) {
  40. String curr = q.poll();
  41. if (!graph.containsKey(curr)) graph.put(curr, new HashSet<>());
  42. char[] chs = curr.toCharArray();
  43. for (int i = 0; i < chs.length; i++) {
  44. char ch = chs[i];
  45. for (char c = 'a'; c <= 'z'; c++) {
  46. if (c == ch) continue;
  47. chs[i] = c;
  48. String next = new String(chs);
  49. if (next.equals(end)) flag = true;
  50. if (!dict.contains(next) || used.contains(next)) continue;
  51. graph.get(curr).add(next);
  52. q.add(next);
  53. layer_used.add(next);
  54. }
  55. chs[i] = ch;
  56. }
  57. }
  58. step += 1;
  59. used.addAll(layer_used);
  60. }
  61. return -1;
  62. }

  

图-搜索-BFS-DFS-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. [LeetCode] 126. 单词接龙 II

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

  4. 126. 单词接龙 II

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

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

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

  6. PAT A1021 Deepest Root (25 分)——图的BFS,DFS

    A graph which is connected and acyclic can be considered a tree. The hight of the tree depends on th ...

  7. 搜索入门_简单搜索bfs dfs大杂烩

    dfs题大杂烩 棋盘问题  POJ - 1321 和经典的八皇后问题一样.  给你一个棋盘,只有#区域可以放棋子,同时同一行和同一列只能有一个棋子. 问你放k个棋子有多少种方案. 很明显,这是搜索题. ...

  8. hdu 4771 Stealing Harry Potter's Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: ...

  9. lintcode 单词接龙II

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

随机推荐

  1. 用hugo建博客的记录 · 老张不服老

    前后累计折腾近6个小时,总算把搭建hugo静态博客的整个过程搞清楚了.为什么用了这么久?主要还是想偷懒,不喜欢读英文说明.那就用中文记录一下过程吧.还是中文顺眼啊. 某日发现自己有展示些东西给外网的需 ...

  2. 改了改之前那个很糙的XXX

    将就着用X度去爬吧 <?php echo "***************************************\r\n"; echo "* SubDom ...

  3. C++扬帆远航——15(项目二,太乐了)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:tailezhanshi.cpp * 作者:常轩 * 微信公众号 ...

  4. 视频描述(Video Captioning)近年重要论文总结

    视频描述 顾名思义视频描述是计算机对视频生成一段描述,如图所示,这张图片选取了一段视频的两帧,针对它的描述是"A man is doing stunts on his bike", ...

  5. Spring编译后没有xml配置文件解决方法

    问题描述 在使用Maven来构建Spring项目的时候,使用下面代码来读取Spring配置文件. ClassPathXmlApplicationContext context = new ClassP ...

  6. MySQL之单表多表查询

    #1.单表查询 #单表查询语法 select <字段1,字段2....> from <表名> where <表达式> group by field 分组 havin ...

  7. 从头认识js-js的发展历史

    JavaScript简介 JavaScript诞生于1995年,当时,它的主要目的是处理以前有服务端语言(如Perl)负责的一些输入验证操作. JavaScript简史 1995年2月当时就职于Net ...

  8. 原生js实现replace方法

    今天看到有人提问js的replace方法怎么实现的,自己就试了试js手册里的String对象的介绍replace大概是这样: string.replace(regexp, replacement) 第 ...

  9. springmvc 的@ResponseBody 如何使用JSONP?

    JSONP解释 在解释JSONP之前,我们需要了解下”同源策略“这个概念,这对理解跨域有帮助.基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文 ...

  10. Mac 下 Docker 运行较慢的原因分析及个人见解

    在mac 使用 docker 的时候,我总感觉程序在 docker 下运行速度很慢,接下来我一一分析我遇到的问题,希望大家能进行合理的讨论和建议. 问题: valet 下打开 laravel 首页耗时 ...