120-单词接龙

给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列

比如:

每次只能改变一个字母。

变换过程中的中间单词必须在字典中出现。

注意事项

  • 如果没有转换序列则返回0。
  • 所有单词具有相同的长度。
  • 所有单词都只包含小写字母。

样例

给出数据如下:

start = "hit"

end = "cog"

dict = ["hot","dot","dog","lot","log"]

一个最短的变换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",

返回它的长度 5

标签

领英 宽度优先搜索

思路

可以将此题理解为求图中两点的最短路径,dict 中每个单词是一个节点,start 与 end 也是图中的节点,若两个单词中只有一个字母不同(如 "hit" "hot" "dog")在,则这两个节点是联通的。故问题就转化成了在图中求节点 start 到节点 end 的最短路径。

因为只需要知道路径长度而非具体路径,所以可以简单使用宽度优先搜索,从 start 开始搜索 end,每扩大一层,路径长度 +1

方法一(最开始想到的,但提交超时)

使用队列 path 记录搜索顺序,pathCount 记录每个节点与 start 节点的距离(即路径长度),每次将与对列的头节点相连且未遍历的节点加入到队列并标记其已经遍历,更新此节点距离

code

  1. class Solution {
  2. public:
  3. /**
  4. * @param start, a string
  5. * @param end, a string
  6. * @param dict, a set of string
  7. * @return an integer
  8. */
  9. int ladderLength(string start, string end, unordered_set<string> &dict) {
  10. // write your code here
  11. int size = dict.size();
  12. if (size <= 0) {
  13. return 0;
  14. }
  15. dict.insert(end);
  16. map<string, bool> isVisited;
  17. map<string, int> pathCount;
  18. queue<string> path;
  19. path.push(start);
  20. isVisited[start] = true;
  21. pathCount[start] = 1;
  22. pathCount[end] = 0;
  23. while (!path.empty()) {
  24. string last = path.front();
  25. path.pop();
  26. for (string str : dict) {
  27. if (isVisited[str] == false && isConnect(str, last)) {
  28. path.push(str);
  29. isVisited[str] = true;
  30. pathCount[str] = pathCount[last] + 1;
  31. if (str == end) {
  32. return pathCount[end];
  33. }
  34. }
  35. }
  36. }
  37. return pathCount[end];
  38. }
  39. bool isConnect(string str1, string str2) {
  40. int distance = 0;
  41. for (int i = 0; i < str1.size(); i++) {
  42. if (str1[i] != str2[i]) {
  43. distance++;
  44. if (distance > 1) {
  45. return false;
  46. }
  47. }
  48. }
  49. if (distance == 1) {
  50. return true;
  51. }
  52. else {
  53. return false;
  54. }
  55. }
  56. };

方法二(AC)

网上普遍的解法,在遍历节点的相邻节点处做了优化,在得到队列头结点时,枚举所有与头结点相连的节点值,并判断此值是否在图中(即 dict 中)。若此节点未被遍历过(即此节点存在于 dict),将其加入队列并更新距离,然后将此节点删除(减少搜索代价),否则,继续枚举

code

  1. class Solution {
  2. public:
  3. /**
  4. * @param start, a string
  5. * @param end, a string
  6. * @param dict, a set of string
  7. * @return an integer
  8. */
  9. int ladderLength(string start, string end, unordered_set<string> &dict) {
  10. // write your code here
  11. int size = dict.size();
  12. if (size <= 0) {
  13. return 0;
  14. }
  15. if(start.size() == end.size() && start.size() == 1) {
  16. return 1;
  17. }
  18. map<string, int> pathCount;
  19. queue<string> path;
  20. path.push(start);
  21. pathCount[start] = 1;
  22. dict.erase(start);
  23. dict.insert(end);
  24. while (dict.size() > 0 && !path.empty()) {
  25. string last = path.front();
  26. path.pop();
  27. for (int i = 0; i < last.size(); i++) { // 枚举可能相连的节点值
  28. string str = last;
  29. for (char j = 'a'; j <= 'z'; j++) { // 枚举可能相连的节点值
  30. if (str[i] == j) {
  31. continue;
  32. }
  33. else {
  34. str[i] = j;
  35. }
  36. if (dict.find(str) != dict.end()) { // 枚举的值在图中存在且未被遍历
  37. path.push(str);
  38. pathCount[str] = pathCount[last] + 1;
  39. dict.erase(str);
  40. }
  41. if (str == end) { // 找到
  42. return pathCount[end];
  43. }
  44. }
  45. }
  46. }
  47. return 0;
  48. }
  49. };

lintcode-120-单词接龙的更多相关文章

  1. 120. 单词接龙 (BFS)

    描述 给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列 比如: 每次只能改变一个字母. 变换过程中的中间单词必须在字典中出现. 如果没有转换序列则返回0. 所有单词 ...

  2. NOIP2000单词接龙[DFS]

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...

  3. Noip2000 T3 单词接龙

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...

  4. 洛谷 P1019 单词接龙 Label:dfs

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...

  5. 【wikioi】1018 单词接龙

    题目链接 算法:DFS+考你阅题 题目描述: 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中 ...

  6. NOIP2000 单词接龙

    题三.  单词接龙                (27分)    问题描述    单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的 ...

  7. 1172: 单词接龙(XCOJ 暴力DFS)

    1172: 单词接龙 时间限制: 1 Sec  内存限制: 128 MB提交: 12  解决: 5 标签提交统计讨论版 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词 ...

  8. 单词接龙(dragon)

    单词接龙(dragon) 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次) ...

  9. NOIP2000提高组 单词接龙

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙" ...

  10. 洛谷 P1019 单词接龙【经典DFS,温习搜索】

    P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在 ...

随机推荐

  1. Iframe 定义内联的子窗口(框架)

    1.Iframe 定义内联的子窗口(框架),用于在网页内显示网页 语法: <iframe src="URL"></iframe>URL 指向隔离页面的位置, ...

  2. pci枚举初始化部分(2)

    1.2.8判断pcie设备是否支持雷电技术 Intel具有一种基于Thunderbolt技术的PCIE变体,它结合了DisplayPort和PCIe协议,与Mini DisplayPort兼容. Th ...

  3. Windos10 mysql-8.0.13安装手顺

    一.下载 1.1 官方下载地址:https://dev.mysql.com/downloads/mysql/ ,点击Download 1.2 点击 No thanks,just start my do ...

  4. UVA 514 - Rails ( 铁轨)

    from my CSDN: https://blog.csdn.net/su_cicada/article/details/86939523 例题6-2 铁轨(Rails, ACM/ICPC CERC ...

  5. windows server dump文件

    1. mini dump: ***** 需要包含 dbghelp.dll 库 ****mini_dump.h文件: // reference:https://msdn.microsoft.com/zh ...

  6. js scroll nav

    http://jsfiddle.net/cse_tushar/Dxtyu/141/http://ironsummitmedia.github.io/startbootstrap-scrolling-n ...

  7. JQuery补充——获取与设置表单值

    //写jQuery代码时注意前面一定要记得加$(function(){});,在文档加载完成后进行代码的编写 使用jQuery的表单对象属性来选择被选中的项::checked,详见文档选择器部分 根据 ...

  8. 20155210 2016-2017-2《Java程序设计》课程总结

    20155210 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 预备作业1:你期望的师生关系 预备作业2:做中学 预备作业3:虚拟机安装 第一周作业:教材 ...

  9. 20155220吴思其 实验2 Windows口令破解

    实验目的: 了解Windows口令破解原理 对信息安全有直观感性认识 能够运用工具实现口令破解 实验人数 每组一人 系统环境 windows 实验工具 LC5 SuperDic 实验原理 口令破解方法 ...

  10. 20155313 实验二《Java面向对象程序设计》实验报告

    20155313 实验二<Java面向对象程序设计>实验报告 一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. ...