leetcode word ladder 2

来源:互联网 发布:用c语言编写圆的面积 编辑:程序博客网 时间:2024/05/14 23:11


15-05-10 更新,按照最下面的解法进行优化,得到AC代码,并且比他快。值得一开心。

class WordNode {public:  string value;  unordered_set<WordNode*> Parents;  WordNode(string v) :value(v) { }};vector<vector<string>> gres;vector<string> gtmp;void checkOneNode(string end, WordNode* node) {  gtmp.push_back(node->value);  if (node->value == end) {    vector<string> tmp_res = gtmp;    gres.push_back(tmp_res);    gtmp.pop_back();    return;  }  for (auto it : node->Parents) {    checkOneNode(end, it);  }  gtmp.pop_back();}vector<vector<string>> findLadders(    string start, string end,    unordered_set<string> &dict) {  dict.insert(start);  WordNode* start_node = NULL;  WordNode* end_node = new WordNode(end);  unordered_map<string, WordNode*> curr_flow, next_flow;  curr_flow[end] = end_node;  string current_word = "";  int n = end.length(), ch;  string a;  //construct a reverse tree  //first create end node, then find words can transform to end,   //and create edge(word, end), do it recursively until find start.  bool done = false;//if find the start, stop  while (!done && !curr_flow.empty()) {    for (auto it : curr_flow) {      current_word = it.first;      for (int j = 0; j < n; j++) {        ch = current_word[j] - 'a';        for (int k = 0; k < 26; k++) {          if (k == ch) continue;          current_word[j] = 'a' + k;          if (dict.find(current_word) != dict.end()) {            //first time add a word to the tree, create it's node            if (next_flow[current_word] == NULL) {              next_flow[current_word] = new WordNode(current_word);              if (current_word == start) {                done = true;                start_node = next_flow[current_word];              }            }            //create edge(new_word, current_layer_word)            next_flow[current_word]->Parents.insert(it.second);          }        }//end of 26 letters        current_word[j] = 'a' + ch;      }//end of word's length    }//end of curr_flow    curr_flow = next_flow;    next_flow.clear();    for (auto it : curr_flow) dict.erase(it.first);  }  if (!done) {    return vector<vector<string>>();  }  //deep first search for ladders  checkOneNode(end, start_node);  return gres;}



做了三天。从一开始的只会用遍历,到后来优化遍历条件,再到尝试用图和BFS做,真是脑子不够了。

还是不够AC,太慢了。

struct MapNode{public:bool added;string val;list<MapNode *> neighbors;vector<list<MapNode *>> routes;MapNode(string s) :added(false), val(s){}void RemoveNeighbor(string s);};vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {vector<vector<string>> res;string a;int n = start.length();int i = 0, difcount = 0;while (i < n){if (start[i] != end[i++])difcount++;if (difcount>1)break;}if (difcount == 1){vector<string> tmp;tmp.push_back(start), tmp.push_back(end);res.push_back(tmp);return res;}MapNode *sp = new MapNode(start);MapNode *ep = new MapNode(end);list<MapNode *> nodelist;nodelist.push_back(sp), nodelist.push_back(ep);//build mapfor (auto it : dict){MapNode *tmp = new MapNode(it);for (auto qit : nodelist){i = 0, difcount = 0;a = qit->val;while (i < n){if (a[i] != it[i++])difcount++;if (difcount > 1)break;}if (difcount == 1){qit->neighbors.push_back(tmp);tmp->neighbors.push_back(qit);}}nodelist.push_back(tmp);}/**///bsfqueue<MapNode *> q;sp->added = true;list<MapNode *> st;st.push_back(sp);sp->routes.push_back(st);q.push(sp);int count = 1;while (q.size()>0){MapNode *qtmp = q.front();q.pop();if (count == 0){count = q.size();}count--;for (auto qit = qtmp->neighbors.begin(); qit != qtmp->neighbors.end(); qit++){MapNode *tmp = *qit;tmp->neighbors.remove(qtmp);if (tmp->routes.size() == 0){for (auto rit : qtmp->routes){rit.push_back(tmp);tmp->routes.push_back(rit);}}else{list<MapNode *> prelist = qtmp->routes.front();list<MapNode *> nextlist = tmp->routes.front();if (prelist.size() + 1 > nextlist.size())continue;if (prelist.size() + 1 < nextlist.size())tmp->routes.clear();for (auto rit : qtmp->routes){rit.push_back(tmp);tmp->routes.push_back(rit);}}if (!tmp->added){tmp->added = true;q.push(tmp);}}if (count == 0 && ep->routes.size()>0){break;}}for (auto rit : ep->routes){vector<string> tmp;for (auto mnode : rit){tmp.push_back(mnode->val);}res.push_back(tmp);}return res;}



2015-05-10更新一个思路,比之前好一些,不过还是不够AC。

bool isAlike(string a, string b) {  int c = 0, n = a.length();  for (size_t i = 0; i < n; i++) {    if (a[i] != b[i]) c++;    if (c > 1) return false;  }  return c == 1;}class WordNode {public:  string value;  unordered_set<WordNode*> Parents;  WordNode(string v) :value(v) { }};vector<vector<string>> gres;vector<string> gtmp;void checkOneNode(string end, WordNode* node) {  gtmp.push_back(node->value);  if (node->value == end) {    vector<string> tmp_res = gtmp;    gres.push_back(tmp_res);    gtmp.pop_back();    return;  }  for (auto it : node->Parents) {    checkOneNode(end, it);  }  gtmp.pop_back();}vector<vector<string>> findLadders(    string start, string end,    unordered_set<string> &dict) {  vector<vector<string>> path;  vector<string> res;  vector<vector<string>> ress;  if (isAlike(start, end)) {    res.push_back(start);    res.push_back(end);    ress.push_back(res);    return ress;  }  swap(start, end);//trying to build a reverse tree  unordered_set<WordNode*> vec_dict;  int index = 0;  for (auto dit : dict) {    WordNode* curr_node = new WordNode(dit);    vec_dict.insert(curr_node);  }  WordNode* end_node = new WordNode(end);  vec_dict.insert(end_node);  return ress;  WordNode* root = new WordNode(start);  WordNode* wn_pointer = root;  unordered_set<WordNode*> flow[2];  int curr_flow = 0, other_flow = 1;  flow[curr_flow].insert(root);  string current_word = "";  int i, difcount, n = end.length();  string a;  //construct the tree  bool done = false, empty = false;//if find the end, stop  while (!done && !empty) {    for (auto it : flow[curr_flow]) {      current_word = it->value;      empty = true;      //find current_word's transformable words in dict      for (auto dit : vec_dict) {        i = 0;        a = dit->value;                while (i < n){          if (a[i] != current_word[i++]) {            a[i - 1] = current_word[i - 1];            break;          }        }        if (a == current_word) {          empty = false;          dit->Parents.insert(it);          flow[other_flow].insert(dit);          if (dit->value == end) {            done = true;//if reach the end          }        }      }//end of find current_word's transformable words    }//end of curr_flow    flow[curr_flow] = unordered_set<WordNode*>();    curr_flow = other_flow;    other_flow = 1 - curr_flow;    for (auto it : flow[curr_flow]) vec_dict.erase(it);    if (empty && !flow[curr_flow].empty()) empty = false;  }  if (!done) {    return ress;  }  //deep first search for ladders  checkOneNode(start, end_node);  return gres;}


看看别人怎么做的吧。


经过几天的不断学习(0 0),终于AC了。。 还是改进别人的代码做的。

class Solution {public:unordered_multimap<string, string> lmap;vector<vector<string>> res;void getPath(string curr, string end, vector<string> path){if (curr == end){path.push_back(end);res.push_back(path);return;}path.push_back(curr);unordered_multimap<string, string>::iterator it;pair<unordered_multimap<string, string>::iterator, unordered_multimap<string, string>::iterator > range = lmap.equal_range(curr);for (it = range.first; it != range.second; it++){getPath(it->second, end, path);}path.pop_back();}vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {string a;int n = start.length();//1. push end, find all next level words and push the pairs into lmap;//2. find all next level words and push the pairs into lmap until start in lmap;//3. find path and save in resunordered_set<string> last_layer, curr_layer;//unordered_set<string> levels[2];  //takes about double time//int currl = 0, prevl = 1;int itmp, i, j;string stmp;curr_layer.insert(end);dict.insert(start);bool flag = false;while (curr_layer.size() > 0 || last_layer.size() > 0){for (unordered_set<string>::iterator it = last_layer.begin(); it != last_layer.end(); it++){dict.erase(*it);}last_layer.clear();for (unordered_set<string>::iterator it = curr_layer.begin(); it != curr_layer.end(); it++){for (i = 0; i < n; i++){stmp = *it;itmp = stmp[i] - 'a';for (j = 1; j < 26; j++){stmp[i] = (itmp + j) % 26 + 'a';if (dict.find(stmp) != dict.end()){lmap.insert(make_pair(stmp, *it));last_layer.insert(stmp);}}}}curr_layer = last_layer;if (curr_layer.count(start) > 0){break;}}vector<string> path;if (lmap.size() > 0)getPath(start, end, path);return res;}    };


0 0