zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    继承与多态
    String作业
    课后作业及动手动脑
    作业3
    动手动脑
    实验任务四
    动手动脑
    课堂练习01
    《大道至简》第一章读后感伪代码
    C++常用编程关键字
  • 原文地址:https://www.cnblogs.com/weiyi-mgh/p/6665320.html
Copyright © 2011-2022 走看看