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. 学习tp5的第三天(模型)

    一.模型 1.定义基础模型 <?php namespace app\index\model; use think\Model; class User extends Model{ // 设置完整 ...

  2. SVN(独立安装)-1.9.7 centos 6.5(64位)

    说明: 运行方式: 基于Apache的http.https网页访问形式: 基于svnserve的独立服务器模式. 数据存储方式: 在Berkeley DB数据库中存储数据: 使用普通的文件FSFS存储 ...

  3. LVM实操

    说明 以下所有操作都基于centos6.9 什么是LVM LVM是逻辑盘卷管理(Logical Volume Manager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬 ...

  4. 1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。

    li = []with open('lo', encoding='utf-8', mode='r') as f1: for i in f1: l2=i.strip().split() dic = {' ...

  5. 两组数据的均值是否具有显著差异的T检验

    最近在做分析的时候,遇到了T检验,然而对于没有统计学背景的人来说完全不知如何下手 当然了,遇到问题第一反应就是百度. 果然百度出来了很多链接,当时第一次直接选择了用Excel去做T检验.下面是源数据 ...

  6. SQLSERVER字符串处理函数

    sqlserver提供了一系列字符串处理函数:substring.left.right.len.charindex.patindex.replace.replicate.stuff.upper.low ...

  7. Verilog的一些系统任务(二)

    $monitor 任务$monitor提供了监控和输出参数列表中的表达式或变量值的功能. 格式: $monitor(p1,p2,...,pn);   $monitor;        $monitor ...

  8. thinkphp查询:

    $Role=D('role'); //查询数据表 $role_data = $Role->order('role_id')->group('role_name')->select() ...

  9. [agc004D]Teleporter

    Description 传送门 Solution 依题意我们可以知道,以2-n为出发点的边和1号节点会构成一课树(不然2-n号节点无法都达到首都). 为了让2-n号节点中,离1号节点的距离<k的 ...

  10. 成都Uber优步司机奖励政策(4月15日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...