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

class Solution {
public:
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return an integer
*/
int ladderLength(string start, string end, unordered_set<string> &dict) {
// write your code here
int size = dict.size();
if (size <= 0) {
return 0;
} dict.insert(end);
map<string, bool> isVisited;
map<string, int> pathCount;
queue<string> path; path.push(start);
isVisited[start] = true;
pathCount[start] = 1;
pathCount[end] = 0; while (!path.empty()) {
string last = path.front();
path.pop();
for (string str : dict) {
if (isVisited[str] == false && isConnect(str, last)) {
path.push(str);
isVisited[str] = true;
pathCount[str] = pathCount[last] + 1;
if (str == end) {
return pathCount[end];
}
}
}
}
return pathCount[end];
} bool isConnect(string str1, string str2) {
int distance = 0;
for (int i = 0; i < str1.size(); i++) {
if (str1[i] != str2[i]) {
distance++;
if (distance > 1) {
return false;
}
}
}
if (distance == 1) {
return true;
}
else {
return false;
}
}
};

方法二(AC)

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

code

class Solution {
public:
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return an integer
*/
int ladderLength(string start, string end, unordered_set<string> &dict) {
// write your code here
int size = dict.size();
if (size <= 0) {
return 0;
}
if(start.size() == end.size() && start.size() == 1) {
return 1;
} map<string, int> pathCount;
queue<string> path; path.push(start);
pathCount[start] = 1; dict.erase(start);
dict.insert(end); while (dict.size() > 0 && !path.empty()) {
string last = path.front();
path.pop();
for (int i = 0; i < last.size(); i++) { // 枚举可能相连的节点值
string str = last;
for (char j = 'a'; j <= 'z'; j++) { // 枚举可能相连的节点值
if (str[i] == j) {
continue;
}
else {
str[i] = j;
}
if (dict.find(str) != dict.end()) { // 枚举的值在图中存在且未被遍历
path.push(str);
pathCount[str] = pathCount[last] + 1;
dict.erase(str);
}
if (str == end) { // 找到
return pathCount[end];
}
}
}
} return 0;
}
};

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. 高性能MySQL--MySQL数据类型介绍和最优数据类型选择

    MySQL支持的数据类型很多,那么选择合适的数据类型对于获得高性能就至关重要.那么就先了解各种类型的优缺点! 一.类型介绍 1.整型类型 整型类型有: TINYINT,SMALLINT,MEDIUMI ...

  2. MongoDB4.0在windows10下的安装与服务配置

    本地安装及网页测试 在官网下载最新的安装文件 下载地址 : https://www.mongodb.com/download-center#community 可以在MongoDB官网选择Commun ...

  3. 我的 Delphi 学习之路 —— Delphi 的安装

    标题:我的 Delphi 学习之路 -- Delphi 的安装 作者:断桥烟雨旧人伤 1. Delphi 版本的选择 Delphi 版本众多,我该选择哪一个,这确实是个问题,自从 Borland 公司 ...

  4. 嵌入式C语言自我修养 07:地址对齐那些事儿

    7.1 属性声明:aligned GNU C 通过 __atttribute__ 来声明 aligned 和 packed 属性,指定一个变量或类型的对齐方式.这两个属性用来告诉编译器:在给变量分配存 ...

  5. Parallel Pattern Library(PPL)学习笔记

    关于PPL是什么,可以搜索关键字MSDN PPL了解详情.这里谈一下困扰自己好一阵子的一个地方--task chain中抛出异常的处理,一来可为其他码农同行参考,二来给自己做个记录,以免日后忘却. V ...

  6. linux——高级文本处理命令之wc、cut、sort

    1.  wc :Word Count 命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出 1.1 命令格式: wc [选项]文件... 1.2 命令参数: -c 统计字节数. -l  ...

  7. MFC-控件操作及数据交换

    对控件进行操作函数如下: 1.ShowWindow() TURE为显示控件,FALSE为隐藏该控件: if(条件) GetDlgItem(ID)->ShowWindow(TRUE);//满足条件 ...

  8. 20155323刘威良第一次实验 Java开发环境的熟悉(Linux + IDEA)

    20155323刘威良第一次实验 Java开发环境的熟悉(Linux + IDEA) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序 ...

  9. 简单的Slony-I设置实例 II

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页 接前面例子, 简单的Slony-I设置实例 这次我 ...

  10. Qt开发者关于QThread的咆哮——你们都用错了

    Qt开发者关于QThread的咆哮——你们都用错了 我们(Qt用户)正广泛地使用IRC来进行交流.我在Freenode网站挂出了#qt标签,用于帮助大家解答问题.我经常看到的一个问题(这让我不厌其烦) ...