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:
- Only one letter can be changed at a time.
- 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; }