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. [原]nginx 一下快一下慢的问题

    在本机用thinkphp建了一个小网站,没任何问题,发布到云空间,就出现访问很慢的情况,而且是一下快一下慢,奇数次快,偶数次慢 换了一台win10的笔记本,情况一样,更新了phpstudy更新了thi ...

  2. HBase操作一

    package Hbase; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.a ...

  3. WOT干货大放送:大数据架构发展趋势及探索实践分享

      WOT大数据处理技术分会场,PingCAP CTO黄东旭.易观智库CTO郭炜.Mob开发者服务平台技术副总监林荣波.宜信技术研发中心高级架构师王东及商助科技(99Click)顾问总监郑泉五位讲师, ...

  4. Vue2.5入门-3

    安装和使用 全局安装vue npm install --global vue-cli 创建基于webpack模板的新项目 vue init webpack my-project 安装依赖 cd my- ...

  5. 微信小程序 微信支付

    微信小程序前端自处理: //时间戳 timeStamp() { return parseInt(new Date().getTime() / 1000) + '' }, //随机数 randomStr ...

  6. 验证码生成工具——Jcaptcha

    <dependency> <groupId>com.octo.captcha</groupId> <artifactId>jcaptcha</ar ...

  7. XMAPP 的安装与配置

    1.XMAPP简介 1.1.XAMPP(Apache+MySQL/MariaDB+PHP+Perl)   开头的X代表X-OS,代表可以在任何常见操作系统下使用,包括Windows.Mac.Linux ...

  8. 【转载】Direct3D基础知识

    原文:Direct3D基础知识 重新从头开始学习DX,以前太急于求成了,很多基础知识都没掌握就开始写程序了,结果出了问题很难解决.   1.       D3D体系结构 D3D与GDI处与同一层次,区 ...

  9. 【洛谷P4178】Tree

    题面 题解 感觉和\(CDQ\)分治一样套路啊 首先,构建出点分树 对于每一层分治重心,求出它到子树中任意点的距离 然后\(two-pointers\)计算满足小于等于\(K\)的点对数目,加入答案 ...

  10. zedboard学习(1)OLED驱动显示图像

    1. 干点啥?驱动一下上面的屏吧 2. 找个代码研究一下,cat命令用于读取文件(普通文件或设备文件)的内容并进行输出.据说板子已经做好OLED的驱动了,驱动映射为/dev/zed_oled,所以直接 ...