leetcode 126. Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

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:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值