【原创】leetCodeOj --- Word Ladder II 解题报告 (迄今为止最痛苦的一道题)
原题地址:
https://oj.leetcode.com/submissions/detail/19446353/
题目内容:
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Note:
- All words have the same length.
- All words contain only lowercase alphabetic characters.
方法:
在这里我分享下做这道题的心路,不,思路历程。
首先第一时间想到BFS,打算正常BFS,但是跟一般的BFS标记结点时不一样,由于可能通过不同路径到达,所以入队前不能标记结点,而是出队时扩展子结点前标记。
结果:TLE
然后考虑到,A、B、C、D到能某个结点,比如说F时,可能会重复计算F到终点的路径。考虑先BFS一次求出最短路径作为fullstep的参数,然后以类似动态规划的思路来记录下子问题的结果。其中具体的实现非常的复杂,同样的点,必须在固定的步数内才算有解。
结果:TLE
又想到,用unordered_set或者unordered_map装字符串,计算hash值时要遍历整个字符串,这个时候不如整数快。于是,就想到不记录字符串,而记录字符串的地址。字符串在从输入获得的set中。由于int损失了精度,就用long long来存。
结果:TLE
没办法了,想到返回子问题解的时候返回的是整个vector,有复制过程,那就换,换成指针,不复制整个vector了。
结果:TLE
干,那就提前建图!提前建好图,在图上做这一坨玩意,就不用老是重复拿26个字母穷举所有位置的情况了!
结果:TLE
最后的最后的最后,有点想放弃了,在意识模糊的情况下,就采用了提前建图 + BFS的思路。
结果居然TM AC了!
全部代码:
class Solution { public:
unordered_map<long long,vector<long long>> map; // 提前建图
unordered_set<long long> mark; // 标记某个点是否已经访问过
struct node {
int len;
node *father;
string *self;
}; void generateMap(unordered_set<string> &dict) {
unordered_set<string> :: iterator it1;
unordered_set<string> :: iterator it2;
unordered_set<long long> :: iterator it3;
unordered_set<long long> used;
for (it1 = dict.begin(); it1 != dict.end(); ++ it1) {
vector<long long> tmp;
map[(long long) & (*it1)] = tmp;
}
for (it1 = dict.begin(); it1 != dict.end(); ++ it1) {
string *now = (string *) & (*it1);
used.insert((long long) now);
for (int i = 0; i < (*now).size(); ++ i) {
char pre = (*now)[i];
for (int j = 'a'; j <= 'z'; ++ j) {
if (j == pre)
continue;
(*now)[i] = j;
it2 = dict.find(*now);
if (it2 != dict.end()) {
it3 = used.find((long long) & (*it2));
if (it3 == used.end()) {
map[(long long) now].push_back((long long) & (*it2));
map[(long long) & (*it2)].push_back((long long) now);
}
}
}
(*now)[i] = pre;
}
}
} vector<string> generateVector(node *tmp) {
vector<string> res;
while (tmp) {
res.push_back(*(tmp->self));
tmp = tmp->father;
}
return res;
} vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
generateMap(dict);
queue<node> myque;
unordered_set<string> :: iterator it1;
vector<vector<string>> res;
vector<node> tmp;
node startnode;
it1 = dict.find(end);
startnode.len = 1;
startnode.father = NULL;
startnode.self = (string *) & (*it1);
myque.push(startnode);
it1 = dict.find(start);
string *fin = (string *)&(*it1);
while (!myque.empty()) {
node now = myque.front();
node *fa = new node;
*fa = now;
if (now.self == fin) {
vector<string> lst = generateVector(fa);
res.push_back(lst);
int limit = now.len;
myque.pop();
while (!myque.empty()) {
node last = myque.front();
if (last.self == fin && last.len == limit) {
lst = generateVector(&last);
res.push_back(lst);
}
myque.pop();
}
break;
}
mark.insert((long long)(now.self));
vector<long long> *vecptr = &map[(long long)(now.self)];
for (int i = 0; i < (*vecptr).size(); ++ i) {
unordered_set<long long> :: iterator it2 = mark.find((*vecptr)[i]);
if (it2 == mark.end()) {
node child;
child.len = now.len + 1;
child.father = fa;
child.self = (string *)(*vecptr)[i];
myque.push(child);
}
}
myque.pop();
}
return res;
}
};
后记:
之前那个BFS + 回溯 + DP的方法没能AC太可惜了,我那里指针玩的6得自己都怕,唉。。
【原创】leetCodeOj --- Word Ladder II 解题报告 (迄今为止最痛苦的一道题)的更多相关文章
- LeetCode: Word Ladder II 解题报告
Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation s ...
- LeetCode: Word Break II 解题报告
Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...
- 【原创】leetCodeOj --- Jump Game II 解题报告
原题地址: https://oj.leetcode.com/problems/jump-game-ii/ 题目内容: Given an array of non-negative integers, ...
- 【LeetCode】212. Word Search II 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀树 日期 题目地址:https://leetco ...
- 【LeetCode】140. Word Break II 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归求解 日期 题目地址:https://leetc ...
- 【LeetCode】244. Shortest Word Distance II 解题报告 (C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典保存出现位置 日期 题目地址:https://le ...
- [Leetcode Week5]Word Ladder II
Word Ladder II 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/word-ladder-ii/description/ Descripti ...
- [leetcode]Word Ladder II @ Python
[leetcode]Word Ladder II @ Python 原题地址:http://oj.leetcode.com/problems/word-ladder-ii/ 参考文献:http://b ...
- 【leetcode】Word Ladder II
Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...
随机推荐
- Delphi中编写无输出函数名的DLL文件(有点意思)(400多篇博客)
用 Delphi 用长了,总是发现,有些和 MS 不同的地方.例如,MS 的公开库中,常常隐藏了许多重要函数,这些函数在系统中常常有起着非常巨大的作用.一旦知道如何调用,可以给自己的应用程序提供很强的 ...
- isapi_rewrite运行在.net framework 4.0+iis 6.0环境下404错误解决方案
今天以前的同事让我帮他上服务器看看,他把页面伪静态之后,出现404错误,为什么会出现这样的问题呢,仔细研究才发现,原因如下: 因为ASP.NET4.0在安装的过程中,已经在IIS6做了一些手脚,让它可 ...
- PHP中如何实现 “在页面中一边执行一边输出” 的效果
<?php set_time_limit(0); //在有关数据库的大量数据的时候,可以将其设置为0,表示无限制. ob_end_clean(); //在循环输出前,要关闭 ...
- JavaScript 中的事件类型4(读书笔记思维导图)
Web 浏览器中可能发生的事件有很多类型.如前所述,不同的事件类型具有不同的信息,而“ DOM3级事件”规定了以下几类事件. UI(User Interface,用户界面)事件:当用户与页面上的元素交 ...
- switch case语句里面不能定义对象,有语法错误,除非加一个花括号
最近发现一个问题呢 发现在switch的case里面不能去定义对象了,一定义对象就会报错了 仔细了解了一下在C或者C++中,只要是在任何一对花括号 “{ }”中定义的对象,那么该对象的作用域就局限在这 ...
- bzoj2301(莫比乌斯反演+分块)
传送门:2301: [HAOI2011]Problem b 题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y ...
- Java程序猿学习当中各个阶段的建议
回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议 引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的 ...
- asp.net EF6.0中出现未找到具有固定名称“System.Data.SqlClient”的 ADO.NET提供程序的实体框架提供程序解决办法
出现的错误信息如下所示: 指定的架构无效.错误: DataModel.ssdl(2,2) : 错误 0152: 未找到具有固定名称“System.Data.SqlClient”的 ADO.NET 提 ...
- linux下golang
linux下golang的配置 linux下golang的配置 之前开发golang一直在windows下,今天在linux下试了一下 ,遇到一些梗,比如go 找不到 sync包.花了一小时全部解决, ...
- PPP协议总结
PPP协议总结 PPP协议是一种在点到点链路上传输.封装网络数据包的数据链路层协议,PPP支持同步/异步方式的链路上. 一. PPP支持的链路类型 1. 同步和异步专线 2. 同步拨号链路. 3. 异 ...