[LeetCode] 127. 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:
- 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.
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 单词阶梯的更多相关文章
- LeetCode 127. Word Ladder 单词接龙(C++/Java)
题目: Given two words (beginWord and endWord), and a dictionary's word list, find the length of shorte ...
- [leetcode]127. Word Ladder单词接龙
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...
- leetcode 127. Word Ladder、126. Word Ladder II
127. Word Ladder 这道题使用bfs来解决,每次将满足要求的变换单词加入队列中. wordSet用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...
- Leetcode#127 Word Ladder
原题地址 BFS Word Ladder II的简化版(参见这篇文章) 由于只需要计算步数,所以简单许多. 代码: int ladderLength(string start, string end, ...
- [Leetcode] word ladder 单词阶梯
Given two words (start and end), and a dictionary, find the length of shortest transformation sequen ...
- 127 Word Ladder 单词接龙
给出两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列,转换需遵循如下规则: 每次只能改变一个字母. 变换过程中的 ...
- leetcode@ [127] Word Ladder (BFS / Graph)
https://leetcode.com/problems/word-ladder/ Given two words (beginWord and endWord), and a dictionary ...
- leetcode 127. Word Ladder ----- java
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...
- [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 ...
随机推荐
- Codeforces C. Elections(贪心枚举三分)
题目描述: C. Elections time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- python笔记41-虚拟环境virtualenv
前言 如果你是一个python初学者,我是不建议你搞python虚拟环境的,我看到很多python的初学者同学,使用最新版的pycharm,新建一个工程时候默认就是venu虚拟环境. 然后在使用cmd ...
- python - 对接微信支付(PC)和 注意点
注:本文仅提供 pc 端微信扫码支付(模式一)的示例代码. 关于对接过程中遇到的问题总结在本文最下方. 参考: 官方文档, https://blog.csdn.net/lm_is_dc/arti ...
- lambda表达式格式以及应用场景?
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. add = lambda x, y : x+y print(add(1,2)) # 结果为3 应 ...
- 2019牛客国庆集训派对day1 K题 双向链表练习题 splay区间翻转
题目链接: 解法: 先建n颗平衡树,合并的时候将a中最右的结点翻转到根节点,b中最左的结点翻转到根节点,对合并后的根节点进行标记. #include <bits/stdc++.h> usi ...
- HBase 基本入门篇
无论是 NoSQL,还是大数据领域,HBase 都是非常”炙热”的一门数据库.本文将对 HBase 做一些基础性的介绍,旨在入门. 一.简介 HBase 是一个开源的.面向列的非关系型分布式数据库,目 ...
- MongoDB 4.2 新特性解读 (转载)
MongoDB World 2019 上发布新版本 MongoDB 4.2 Beta,包含多项数据库新特性,本文尝试从技术角度解读. Full Text Search MongoDB 4.2 之前,全 ...
- graphql-query-rewriter 无缝处理graphql 变更
graphql-query-rewriter 是一个graphql schema 变动重写的中间件,可以帮助我们解决在版本变动,查询实体变动 是的问题,从目前已知的技术中我们可选的方案有以下处理变动的 ...
- PHP生成随机数;订单号唯一
//8-12位随机数 function makeRand($num=){ $strand = (; if(strlen($strand)<$num){ $strand = str_pad($st ...
- P1913 L国的战斗之伞兵
题目链接 P1913 L国的战斗之伞兵 思路 从无风点倒着dfs,本来是道大水题,结果输入的时候第二层循环打错了!手残打成i++ 代码 #include<iostream> #includ ...