Word Ladder

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

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.

单词阶梯,前两天的一次笔试里面也有碰到,但个别细节有所不同,比leetcode上面要简化了一些。我首先承认,看到这类题会使劲往编辑距离上面想,想着以二维矩阵来记录变化距离,(当然,本题距离只能为0不可达,1可达),然后再编辑距离矩阵中所搜答案。然而,在分析中就觉得摸不着头脑,有些混乱。在看了网上解析后,才明白过来是要通过图的dps来搜索的,瞬间又一次觉得自己弱爆了。对于,图的搜索中记录路经层数,看了每层后队列中插入空“”字符来记录层数,觉得是一个不错的想法,参见http://www.cnblogs.com/TenosDoIt/p/3443512.html

来说说本题思路:

  本来,单词间通过一次变换可以到达的之间有连线的话,应该是一个无向图,但是,本题中我们要从根节点出发,一次往下链接生成图,每次生成这个单词的节点后就在字典中删除该单词,这样就生成一颗以beginword为根节点的树而非图了。那么接下来要做的就是在这颗树中,寻找到达endword节点的最短路径。按照从根节点开始,逐层往下搜索,第一个到达endword节点的路经即截止,也为最短路径。整个搜索过程中,记录下树的层高,就可以得到结果。在搜索过程中,通过一个队列来按层保存节点,并且当前层入队完后,入队一“”来表示当层遍历完毕,可以顺利地求出最后路经的层高。

注:当前层搜索完了 没有达到endword,且一个下层数据单词都没有,则没有可达路经,立即返回,这个通过一个标志可以做到;

  为了防止字典中可能有多个单词相同,采用了一次转换list到集合set中的方法

  网上找到的好些代码根本ac不了,包括leetcode下面讨论中的代码,也ac不了,其原因还是考虑没有周全

代码:

int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
	if (beginWord == endWord)
		return 0;

	unordered_set<string> wordset;
	for (int i = 0; i < wordList.size(); ++i)
		wordset.insert(wordList[i]);

	bool Hasroad = false;
	deque<string> deq;
	deq.push_back(beginWord);
	deq.push_back("");

	int res = 1;
	while (!deq.empty() && !wordset.empty())
	{
		string str = deq.front();
		deq.pop_front();
		if (str != "")
		{
			for (int i = 0; i < str.size(); ++i)
			{
				char cur_c = str[i];
				for (char c = 'a'; c <= 'z'; ++c)
				{
					if (c == cur_c)
						continue;
					str[i] = c;
					if (str == endWord)
						return res + 1;
					if (wordset.count(str) > 0)
					{
						deq.push_back(str);
						wordset.erase(str);
						Hasroad = true;
					}
				}
				str[i] = cur_c;
			}
		}
		else if (str == "")
		{
			deq.push_back("");
			++res;
			if (Hasroad == false)
				return 0;
			else
				Hasroad = false;
		}
		else if (deq.empty())
			return 0;
	}
	return 0;
}

 

posted @ 2017-04-04 16:29  糯米米一粒  阅读(204)  评论(0)    收藏  举报