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. springmvc手动获取bean

    @Service @Lazy(false) public class SpringContextHolder implements ApplicationContextAware, Disposabl ...

  2. storm整合kafka storm-kafka-client

    pom.xml-注意jar-log4j---------------------<dependencies> <dependency> <groupId>org.a ...

  3. Kotlin函数与Lambda表达式深入

    Kotlin函数: 关于Kotlin函数在之前也一直在用,用fun来声明,回忆下: 下面再来整体对Kotlin的函数进行一个学习. 默认参数(default arguments): 先来定义一个函数: ...

  4. 题解 UVa11609

    题目大意 给定一个正整数 \(n\),请求出所有小于 \(n\) 人的团队如果选出一个人作为队长的不同的方案数(假定这些人两两不相同)对 \(10^9+7\)取模的结果. 分析 即求 \[\sum^n ...

  5. TypeScript语言学习笔记(4)枚举

    枚举 // 数值型枚举 enum Direction { Up = 1, Down, Left, Right, } // Up=0 enum Direction { Up, Down, Left, R ...

  6. python的程序运行时间

    import time start =time.clock() sum= ,): sum=sum+i print(sum ) end = time.clock() print('Running tim ...

  7. 学习:类和对象——对象模型和this指针

    成员变量和成员函数分开存储: 在C++中,类内的成员变量和成员函数分开存储 第一点:空对象占用内存空间1个字节 第二点:只有非静态成员变量才属于类的对象上,非静态成员函数和静态成员函数和静态成员变量不 ...

  8. Spring Security 认证执行流程

    本文基于 Spring Security 5.x 推荐阅读: 项目集成Spring Security SpringSecurity 整合 JWT 一.外层-正常登陆调用 项目启动后会自动寻找 User ...

  9. 基于麦克风阵列的声源定位算法之GCC-PHAT

    目前基于麦克风阵列的声源定位方法大致可以分为三类:基于最大输出功率的可控波束形成技术.基于高分辨率谱图估计技术和基于声音时间差(time-delay estimation,TDE)的声源定位技术. 基 ...

  10. LeetCode 826. Most Profit Assigning Work

    原题链接在这里:https://leetcode.com/problems/most-profit-assigning-work/ 题目: We have jobs: difficulty[i] is ...