LintCode-单词接龙II
来源:互联网 发布:网络市场监管专项行动 编辑:程序博客网 时间:2024/05/29 18:22
LintCode-单词接龙II
给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列 比如: 每次只能改变一个字母。 变换过程中的中间单词必须在字典中出现。注意事项 所有单词具有相同的长度。 所有单词都只包含小写字母。样例给出数据如下:start = "hit"end = "cog"dict = ["hot","dot","dog","lot","log"]返回[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
先直接写了个图+BFS
遍历每两个单词算different,等于1的放进邻接矩阵里面。
然后用没做优化的BFS找end
class Solution {public: /** * @param start, a string * @param end, a string * @param dict, a set of string * @return a list of lists of string */ struct Destination { int num = 0; vector<string> str; }; struct Path { string str; vector<string> path; }; map<string,bool> isPassed; void BFS(queue<Path> &order, vector<vector<string>> &result, map<string, Destination> m, const string end) { int num = order.size(); for (int i = 0; i < num;i++) { Path s = order.front(); isPassed[s.str]=true; order.pop(); if (s.str == end) { result.push_back(s.path); } if (m[s.str].num != 0) { for (auto i : m[s.str].str) { if(!isPassed[i]) { Path p; p.str = i; p.path = s.path; p.path.push_back(i); order.push(p); } } } } if (!order.empty() && result.empty()) BFS(order, result, m, end); return; } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // write your code here dict.insert(start); dict.insert(end); map<string, Destination> m; for (auto i : dict) { Destination d; for (auto j : dict) { int diff = 0; for (int p = 0; p<i.length(); p++) { if (i[p] != j[p]) diff++; } if (diff == 1) { d.num++; d.str.push_back(j); } } m[i] = d; } queue<Path> order; Path s; s.path.push_back(start); s.str = start; order.push(s); vector<vector<string>> result; BFS(order, result, m, end); return result; }};
过了大概七个case后超时,发现光建map就要用O(n
for (auto i : dict) { for (int j = 0; j<i.size(); j++) { for (int k = 0; k<26; k++) { string tmp = i; tmp[j] = 'a' + k; if (dict.find(tmp)!=dict.end() && strcmp(tmp.c_str(), i.c_str())) { m[i].num++; m[i].str.push_back(tmp); } } }}
又多过了一个case,接着是BFS超时
想一想感觉是搜索的时候队列里面会出现大量重复的单词,拖慢速度。
于是做了一个set记录每个单词的“last string”,只有没加入过的next string才能加到队列里面,保证队列里面不会有重复单词。
但这样一来就没办法直接记录path了,于是再利用刚才的set通过BFS反向找一下path,一开始作死想用栈写BFS,结果写了几十行各种出问题放弃了,直接10行递归搞定。
class Solution {public: /** * @param start, a string * @param end, a string * @param dict, a set of string * @return a list of lists of string */ struct Destination { int num = 0; vector<string> str; }; struct Node { unordered_set<string> last; }; map<string, Node> node; map<string, bool> isPassed; vector<vector<string>> result; void DFS(vector<string> path,string str,int count,const string& start,const int& max) { path.push_back(str); if (str == start) { result.push_back(path); reverse(result.back().begin(), result.back().end()); } if (count == max) return; for (auto i : node[str].last) { DFS(path, i, count + 1, start, max); } return; } void BFS(queue<string> &order, map<string, Destination> m, const string start,const string end) { int max=1; while (!order.empty() && !node[end].last.size()) { int num = order.size(); max++; for (int i = 0; i < num; i++) { string s = order.front(); isPassed[s] = true; order.pop(); if (m[s].num != 0) { for (auto i : m[s].str) { if (!isPassed[i]) { if (node[i].last.size() == 0) { order.push(i); } node[i].last.insert(s); } } } } } vector<string> path; DFS(path, end, 1, start, max); return; } vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // write your code here dict.insert(start); dict.insert(end); map<string, Destination> m; for (auto i : dict) { for (int j = 0; j<i.size(); j++) { for (int k = 0; k<26; k++) { string tmp = i; tmp[j] = 'a' + k; if (dict.find(tmp)!=dict.end() && strcmp(tmp.c_str(), i.c_str())) { m[i].num++; m[i].str.push_back(tmp); } } } } queue<string> order; order.push(start); BFS(order, m, start,end); return result; }};
总共跑了500多ms,网上的代码大概300ms,贴下来有空再看
class Solution { public: /** * @param start, a string * @param end, a string * @param dict, a set of string * @return a list of lists of string */ vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) { // write your code here vector<vector<string> > result; set<string> cur; cur.insert(start); set<string> next; map<string, set<string> > parents; unordered_set<string> unused = dict; unused.insert(end); visit(cur, end, next, unused, parents); if (parents.find(end) != parents.end()) { vector<string> buf; generatePath(start, end, parents, buf, result); } return result; } private: void visit(set<string> &cur, string &end, set<string> &next, unordered_set<string> &unused, map<string, set<string> > &parents) { while (parents.find(end) == parents.end() && !unused.empty()) { next.clear(); for (set<string>::iterator it = cur.begin(); it != cur.end(); it++) { string word = *it; string temp = *it; for (int i = 0; i < (*it).length(); i++) { for (char a = 'a'; a <= 'z'; a++) { temp = *it; if (a != word[i]) { temp[i] = a; if (unused.find(temp) != unused.end()) { parents[temp].insert(word); next.insert(temp); } } } } } if (next.empty()) { return; } cur = next; for (set<string>::iterator it = next.begin(); it != next.end(); it++) { unused.erase(*it); } } } void generatePath(string &start, string cur, map<string, set<string> > &parents, vector<string> &buf, vector<vector<string> > &result) { buf.insert(buf.begin(), cur); if (cur == start) { result.push_back(buf); } else { for (set<string>::iterator it = parents[cur].begin(); it != parents[cur].end(); it++) { generatePath(start, *it, parents, buf, result); } } buf.erase(buf.begin()); } };
阅读全文
0 0
- LintCode-单词接龙II
- 单词接龙 II-LintCode
- lintcode-单词接龙-120
- lintcode,单词接龙
- 单词接龙-LintCode
- 单词接龙 II
- ***[Lintcode]Word Ladder 单词接龙
- LINTCODE——单词接龙
- Arithmetic problem | 单词接龙 II
- LintCode 120-单词接龙 广度优先搜索
- LintCode 单词搜索 II
- LintCode : 单词搜索 II
- 单词搜索 II-LintCode
- 单词拆分II-LintCode
- 单词接龙
- 单词接龙
- 单词接龙
- 单词接龙
- ImageView 的 ScaleType 的表现及原理探究
- android自定义View、ViewGroup
- Marriage is Stable
- SpringMVC和ajax文件上传
- 《逆向工程核心原理》学习总结(四)
- LintCode-单词接龙II
- Python中 pip不是内部或外部命令,也不是可运行的程序 或批处理文件。
- HTML5的几种存储方式
- hdu 1180 诡异的楼梯 (BFS)
- ubuntu (16.04) server 英文原版 添加中文语言支持 消除java 程序、mysql 数据库不能处理中文的错误
- BFS:HDU2597-Dating with girls(2) (分时间标记状态)
- 鸟哥Linux学习之——文件内容查看
- 浙大PAT甲级-1012
- 十一、抽象工厂模式——设计模式学习笔记