LintCode-单词接龙II
2017-07-01 20:27
281 查看
LintCode-单词接龙II
先直接写了个图+BFS
遍历每两个单词算different,等于1的放进邻接矩阵里面。
然后用没做优化的BFS找end
过了大概七个case后超时,发现光建map就要用O(n2)。查了一下看到unordered_set的find()函数,于是改成
又多过了一个case,接着是BFS超时
想一想感觉是搜索的时候队列里面会出现大量重复的单词,拖慢速度。
于是做了一个set记录每个单词的“last string”,只有没加入过的next string才能加到队列里面,保证队列里面不会有重复单词。
但这样一来就没办法直接记录path了,于是再利用刚才的set通过BFS反向找一下path,一开始作死想用栈写BFS,结果写了几十行各种出问题放弃了,直接10行递归搞定。
总共跑了500多ms,网上的代码大概300ms,贴下来有空再看
给出两个单词(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< 4000 /span><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(n2)。查了一下看到unordered_set的find()函数,于是改成
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; < b35e span class="hljs-keyword">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()); } };
相关文章推荐
- 单词接龙 II-LintCode
- lintcode 单词接龙II
- LINTCODE——单词接龙
- LintCode 120-单词接龙 广度优先搜索
- lintcode-120-单词接龙
- 单词拆分II-LintCode
- LintCode_单词接龙
- Leetcode 126. 单词接龙 II
- LintCode 单词搜索 II
- Arithmetic problem | 单词接龙 II
- ***[Lintcode]Word Ladder 单词接龙
- 单词搜索 II-LintCode
- LintCode 132-单词搜索II 深度优先
- 单词接龙-LintCode
- lintcode,单词接龙
- 单词接龙 II
- hihocoder1618 单词接龙
- lintcode-medium-N Queens II
- 单词接龙
- lintcode-medium-Permutation Index II