Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
class Solution { vector<vector<string>>re; int minlen; void do_once(string endWord, vector<pair<vector<string>, map<char, vector<string>>> >&candi) { vector<pair<vector<string>, map<char, vector<string>>> >newcandi; for (int i = 0; i < candi.size(); i++) { if (candi[i].first.size() + 2 <= minlen) { string str = candi[i].first[candi[i].first.size()-1]; for (map<char, vector<string>>::iterator it1 = candi[i].second.begin(); it1 != candi[i].second.end(); it1++) { for (int j = 0; j < it1->second.size(); j++) { if (string(it1->second[j].begin() + 1, it1->second[j].end()) == string(str.begin() + 1, str.end())) { int kk = 0; for (int jj = 0; jj < it1->second[j].length(); jj++) if (endWord[jj] != it1->second[j][jj]) kk++; if (kk == 1) { if (candi[i].first.size() + 2 < minlen) { minlen = candi[i].first.size() + 2; re.clear(); vector<string>aa = candi[i].first; aa.push_back(it1->second[j]); aa.push_back(endWord); re.push_back(aa); } else if (candi[i].first.size() + 2 == minlen) { vector<string>aa = candi[i].first; aa.push_back(it1->second[j]); aa.push_back(endWord); re.push_back(aa); } } else if (candi[i].first.size() + kk + 1 <= minlen) { vector<string>aa = candi[i].first; aa.push_back(it1->second[j]); map<char, vector<string>>cc = candi[i].second; cc[it1->first].erase(find(cc[it1->first].begin(), cc[it1->first].end(), it1->second[j])); newcandi.push_back(pair < vector<string>, map<char, vector<string>> > (aa, cc)); } } } } for (int j = 1; j < endWord.length(); j++) { string newstr = str; newstr .erase(j,1); for (int h =0;h< candi[i].second[newstr[0]].size();h++) { string ss = candi[i].second[newstr[0]][h]; ss.erase(j,1); if (newstr == ss) { int kk = 0; for (int jj = 0; jj < candi[i].second[newstr[0]][h].length(); jj++) if (endWord[jj] != candi[i].second[newstr[0]][h][jj]) kk++; if (kk == 1) { if (candi[i].first.size() + 2 < minlen) { minlen = candi[i].first.size() + 2; re.clear(); vector<string>aa = candi[i].first; aa.push_back(candi[i].second[newstr[0]][h]); aa.push_back(endWord); re.push_back(aa); } else if (candi[i].first.size() + 2 == minlen) { vector<string>aa = candi[i].first; aa.push_back(candi[i].second[newstr[0]][h]); aa.push_back(endWord); re.push_back(aa); } } else if (candi[i].first.size() + kk + 1 <= minlen) { vector<string>aa = candi[i].first; aa.push_back(candi[i].second[newstr[0]][h]); map<char, vector<string>>cc = candi[i].second; cc[ss[0]].erase(find(cc[ss[0]].begin(), cc[ss[0]].end(), candi[i].second[newstr[0]][h])); newcandi.push_back(pair < vector<string>, map<char, vector<string>> >(aa, cc)); } } } } } } candi = newcandi; } public: vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) { minlen = wordList.size() + 2; vector<pair<vector<string>, map<char,vector<string>>> >candi; int kkk=0; for (int i = 0; i < beginWord.length(); i++) if (beginWord[i] != endWord[i]) kkk++; if (kkk==1) { vector<string>bb; bb.push_back(beginWord); bb.push_back(endWord); re.push_back(bb); return re; } vector<string>start; start.push_back(beginWord); map<char, vector<string>>bb; for (unordered_set<string>::iterator it = wordList.begin(); it != wordList.end(); it++) bb[(*it)[0]].push_back(*it); candi.push_back(pair<vector<string>, map<char, vector<string>>>(start,bb)); while (!candi.empty()&&candi[0].first.size()+2<=minlen) { do_once(endWord, candi); } return re; } }; int _tmain(int argc, _TCHAR* argv[]) { string beginWord = "cet"; string endWord = "ism"; string words[599] = { "kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob" }; unordered_set<string> wordList; for (int i = 0; i < 599; i++) wordList.insert(words[i]); Solution sl; vector<vector<string>>re=sl.findLadders(beginWord, endWord, wordList); system("pause"); return 0; }
问题二 太慢
思路,换用双向广度优先搜索,从beginword和endword同时开始搜索,在找到第一个答案的那一层找到所有答案后即可返回。
class Solution { public: vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) { vector<vector<string>>re; if (beginWord == endWord || beginWord.length() == 1) { vector<string>rr; rr.push_back(beginWord); rr.push_back(endWord); re.push_back(rr); return re; } int wl = beginWord.length(); for (int i = 0; i < wl; i++) { string s1(beginWord), s2(endWord); s1.erase(i, 1); s2.erase(i, 1); if (s1 == s2) { vector<string>rr; rr.push_back(beginWord); rr.push_back(endWord); re.push_back(rr); return re; } } vector<string>words(wordList.begin(), wordList.end()); map<pair<string,int>, vector<int>>changelist; for (int i = 0; i < words.size(); i++) { for (int j = 0; j < words[0].length(); j++) { string s = words[i]; s.erase(j, 1); changelist[pair<string, int>(s,j)].push_back(i); } } vector<int>a, b; for (int i = 0; i < words.size(); i++) a.push_back(i); map<string, vector<vector<int>>>head, tail; head[beginWord].push_back(b); tail[endWord].push_back(b); bool flag = true; int k = 0; while (k < words.size() && flag) { k++; if (tail.size()>head.size()) { map<string, vector<vector<int>>>newhead; for (map<string, vector<vector<int>>>::iterator ii = head.begin(); ii != head.end(); ii++) { for (int j = 0; j < ii->second.size(); j++) { for (int h = 0; h < wl; h++) { string s = ii->first; s.erase(h, 1); for (int f = 0; f < changelist[pair<string, int>(s,h)].size(); f++) { if (words[changelist[pair<string, int>(s,h)][f]] != ii->first) { vector<int>::iterator ite = find(ii->second[j].begin(), ii->second[j].end(), changelist[pair<string, int>(s,h)][f]); if (ite == ii->second[j].end()) { map<string, vector<vector<int>>>::iterator nn = tail.find(words[changelist[pair<string, int>(s,h)][f]]); if (nn != tail.end()) { for (int g = 0; g < nn->second.size(); g++) { set<int>aa; set<int>a1(ii->second[j].begin(), ii->second[j].end()); set<int>a2(nn->second[g].begin(), nn->second[g].end()); set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), inserter(aa, aa.begin())); if (aa.empty() && (a1.size()>0 || a2.size()>0)) { flag = false; vector<string>sl; sl.push_back(beginWord); for (int d = 0; d < ii->second[j].size(); d++) sl.push_back(words[ii->second[j][d]]); //sl.push_back(words[changelist[s][f]]); for (int d = nn->second[g].size() - 1; d >= 0; d--) sl.push_back(words[nn->second[g][d]]); sl.push_back(endWord); if (find(re.begin(), re.end(), sl) == re.end()) re.push_back(sl); } } } if (flag) { vector<int>xx = ii->second[j]; xx.push_back(changelist[pair<string, int>(s,h)][f]); newhead[words[changelist[pair<string, int>(s,h)][f]]].push_back(xx); } } } } } } } //f = !f; head = newhead; } else { map<string, vector<vector<int>>>newtail; for (map<string, vector<vector<int>>>::iterator ii = tail.begin(); ii != tail.end(); ii++) { for (int j = 0; j < ii->second.size(); j++) { for (int h = 0; h < wl; h++) { string s = ii->first; s.erase(h, 1); for (int f = 0; f < changelist[pair<string, int>(s,h)].size(); f++) { if (words[changelist[pair<string, int>(s,h)][f]] != ii->first) { vector<int>::iterator ite = find(ii->second[j].begin(), ii->second[j].end(), changelist[pair<string, int>(s,h)][f]); if (ite == ii->second[j].end()) { map<string, vector<vector<int>>>::iterator nn = head.find(words[changelist[pair<string, int>(s, h)][f]]); if (nn != head.end()) { for (int g = 0; g < nn->second.size(); g++) { set<int>aa; set<int>a1(ii->second[j].begin(), ii->second[j].end()); set<int>a2(nn->second[g].begin(), nn->second[g].end()); set_intersection(a1.begin(), a1.end(), a2.begin(), a2.end(), inserter(aa, aa.begin())); if (aa.empty() && (a1.size()>0 || a2.size()>0)) { flag = false; vector<string>sl; sl.push_back(beginWord); for (int d = 0; d< nn->second[g].size(); d++) sl.push_back(words[nn->second[g][d]]); //sl.push_back(words[changelist[s][f]]); for (int d = ii->second[j].size() - 1; d >= 0; d--) sl.push_back(words[ii->second[j][d]]); sl.push_back(endWord); if (find(re.begin(), re.end(), sl) == re.end()) re.push_back(sl); } } } if (flag) { vector<int>xx = ii->second[j]; xx.push_back(changelist[pair<string, int>(s, h)][f]); newtail[words[changelist[pair<string, int>(s, h)][f]]].push_back(xx); } } } } } } } //f = !f; tail = newtail; } } return re; } };
accepted