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.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"] Output: 5
Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"] Output: 0
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

给一个单词字典,把一个起始单词变为结束单词,每次只能变化一个字符,而且变化的中间词都在字典中,求最短的变化路径。

本质上是一个求无向无权图的单源最短路径问题,首选的解法是广度优先遍历(BFS)。
beginWord相当于路径的源点,而endWord相当于路径的终点。dictionary中的每个单词相当于一个节点,相互之间只差一个字符的两个单词其对应节点相互邻接,从而构成了一个无向无权图。
为了进行广度优先遍历,我们需要一个队列Queue作为辅助的数据结构。在进入循环之前,先把beginWord添加到队列中以初始化队列;当Queue为空时,结束循环。
由于题目要求的是路径的长度,我们可以用一个变量来记录广度优先遍历的当前层次数,并用一个内循环来完成一层遍历。这样,当找到endWord时,结束遍历,此时该变量的值就是路径的长度。

这道题的场景与图论中求单源最短路径不同之处在于,图论中遍历一个节点的邻接节点通常可以直接从该节点的属性中读取,而这道题中无法直接得到一个单词的邻接单词。
对于这个问题,有两种可以参考的解决思路:
(1)用一个Set来记录已经处理过的单词。每次要求一个单词A的邻接单词时,就遍历字典——如果当前单词不在Set(即还没有被处理过),就把当前单词入队列Queue;否则,表明该单词已经处理过,直接略过。
这种求邻接单词的方法需要遍历整个字典,因此时间复杂度为O(n),其中n表示字典的规模。在最坏情况下,要对字典中的每一个单词都处理之后才能得到这道题的最终结果,因此这种解法的总的时间复杂度是O(n^2)。用到了两个辅助的数据结构——Set和Queue,最坏情形下需要2*n的辅助空间,因此空间复杂度为O(n)。

参考:

http://blog.csdn.net/lemonpi/article/details/78759263

http://www.cnblogs.com/love-yh/p/7136573.html

Java:

class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> known = new HashSet<>();
Queue<String> queue = new LinkedList<>(); queue.offer(beginWord);
for(int i = 2; !queue.isEmpty(); i++) {
int size = queue.size();
for(int j = 0; j < size; j++) {
String str = queue.poll();
known.add(str);
wordList.remove(str);
for(String s : wordList) {
if(!known.contains(s) && isNeighbor(str, s)) {
if(s.equals(endWord)) {
return i; //Found it!
} else {
queue.offer(s);
}
}
}
}
} return 0;
} private boolean isNeighbor(String str1, String str2) {
int length = str1.length();
int diff = 0; for(int i = 0; i < length; i++) {
if(str1.charAt(i) != str2.charAt(i)) {
diff++;
}
} return diff == 1;
}
}

Python: BFS

class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: int
"""
distance, cur, visited, lookup = 0, [beginWord], set([beginWord]), set(wordList) while cur:
next_queue = [] for word in cur:
if word == endWord:
return distance + 1
for i in xrange(len(word)):
for j in 'abcdefghijklmnopqrstuvwxyz':
candidate = word[:i] + j + word[i + 1:]
if candidate not in visited and candidate in lookup:
next_queue.append(candidate)
visited.add(candidate)
distance += 1
cur = next_queue return 0  

C++:

class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict(wordList.begin(), wordList.end());
unordered_map<string, int> m;
queue<string> q;
m[beginWord] = 1;
q.push(beginWord);
while (!q.empty()) {
string word = q.front(); q.pop();
for (int i = 0; i < word.size(); ++i) {
string newWord = word;
for (char ch = 'a'; ch <= 'z'; ++ch) {
newWord[i] = ch;
if (dict.count(newWord) && newWord == endWord) return m[word] + 1;
if (dict.count(newWord) && !m.count(newWord)) {
q.push(newWord);
m[newWord] = m[word] + 1;
}
}
}
}
return 0;
}
};  

类似题目:

[LeetCode] 126. Word Ladder II 词语阶梯 II

All LeetCode Questions List 题目汇总

[LeetCode] 127. Word Ladder 单词阶梯的更多相关文章

  1. LeetCode 127. Word Ladder 单词接龙(C++/Java)

    题目: Given two words (beginWord and endWord), and a dictionary's word list, find the length of shorte ...

  2. [leetcode]127. Word Ladder单词接龙

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  3. leetcode 127. Word Ladder、126. Word Ladder II

    127. Word Ladder 这道题使用bfs来解决,每次将满足要求的变换单词加入队列中. wordSet用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...

  4. Leetcode#127 Word Ladder

    原题地址 BFS Word Ladder II的简化版(参见这篇文章) 由于只需要计算步数,所以简单许多. 代码: int ladderLength(string start, string end, ...

  5. [Leetcode] word ladder 单词阶梯

    Given two words (start and end), and a dictionary, find the length of shortest transformation sequen ...

  6. 127 Word Ladder 单词接龙

    给出两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列,转换需遵循如下规则:    每次只能改变一个字母.    变换过程中的 ...

  7. leetcode@ [127] Word Ladder (BFS / Graph)

    https://leetcode.com/problems/word-ladder/ Given two words (beginWord and endWord), and a dictionary ...

  8. leetcode 127. Word Ladder ----- java

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  9. [LeetCode] 127. Word Ladder _Medium tag: BFS

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

随机推荐

  1. [转载]Linux进程调度原理

    [转载]Linux进程调度原理 Linux进程调度原理 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交 ...

  2. 使用selenium谷歌浏览器驱动配置:

    from selenium import webdriver#导入谷歌浏览器的chrome_driverchrome_driver = r"C:\python36\Lib\site-pack ...

  3. 文件操作时:xreadlines和readlines的区别?

    二者使用时相同,但返回类型不同,xreadlines返回的是一个生成器,readlines返回的是list

  4. [Algorithm] BFS vs DFS

    //If you know a solution is not far from the root of the tree: BFS, because it is faster to get clos ...

  5. [Web] About image: MozJPEG

    Image is quite heavy in web traffic. it is about 53% whole web traffic. It is important to make sure ...

  6. shell脚本sed的基本用法

    sed 我们首先准备了一个测试文件 1. s 替换  将文件中的This替换cyy 在替换的时候如果加入了 -i 选项就会真的替换,但是只会替换每一行的第一个 -n 和 -p 一起使用表示的是打印那些 ...

  7. Redis的移库操作

    1.Redis默认有16个数据库,一般情况下使用0库: 2.移库操作: 将mysets移到一号库: 通过Redis查看器查看: 通过命令查看:

  8. 用pandas进行数据清洗(二)(Data Analysis Pandas Data Munging/Wrangling)

    在<用pandas进行数据清洗(一)(Data Analysis Pandas Data Munging/Wrangling)>中,我们介绍了数据清洗经常用到的一些pandas命令. 接下 ...

  9. 树莓派基于scratch2控制GPIO

    本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/raspberry_scratch2_gpio_control.m ...

  10. IDEA 重新 build Project