题目:

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 beginWordis 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.

分析:

给定起始和终止两个单词,和一个单词列表,要求我们使用列表中的单词将起始和终止单词连接起来,连接的规则是要求每次只改变一个字符,且在列表中存在,终止单词也需要在列表中。

我们可以利用广度优先搜索,从起始单词开始,将每一位字符从a到z依次改变,如果改变后的单词在列表中,就记录下来,并在集合中删去,这样做的目的是为了防止重复的搜索,例如dog-dop-dog,这样是浪费时间的,当新加入的单词和最终单词相同时,返回步骤数即可,如果保存搜索单词的集合(队列)为空时,证明已经搜索结束,且没有找到,返回0即可。

还可以利用双向广度优先搜索进行优化,思想就是同时从起始单词和终止单词开始搜索,也是通过改变字符,且在单词列表中便加入到两个搜索集中,当一侧搜索出来的单词,在另一侧的搜索单词集中,意味着出现了解。至于搜索的次序,如果当一方的集合中的单词数量小于另一方时,就优先从数量小的集合开始搜索。

程序:

C++

class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
//set<string> dict;
unordered_set<string> dict;
for(string s:wordList)
dict.insert(s);
if(dict.count(endWord) == )
return ;
queue<string> q;
q.push(beginWord);
int l = beginWord.length();
int step = ;
while(!q.empty()){
step++;
int len = q.size();
for(int i = ; i < len; ++i){
string word = q.front();
q.pop();
for(int j = ; j < l; ++j){
char ch = word[j];
for(int k = 'a'; k <= 'z'; ++k){
if(k == ch)
continue;
word[j] = k;
if(word == endWord)
return step+;
if(dict.count(word) == )
continue;
q.push(word);
dict.erase(word);
}
word[j] = ch;
}
}
}
return ;
}
};
//Bidirectional BFS
//Runtime: 28 ms, faster than 98.16% of C++ online submissions for Word Ladder.
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
//set<string> dict;
unordered_set<string> dict;
for(string s:wordList)
dict.insert(s);
if(dict.count(endWord) == )
return ;
unordered_set<string> q1;
unordered_set<string> q2;
q1.insert(beginWord);
q2.insert(endWord);
int l = beginWord.length();
int step = ;
while(!q1.empty() && !q2.empty()){
step++;
if(q1.size() > q2.size())
swap(q1, q2);
unordered_set<string> q;
for(string word:q1){
for(int j = ; j < l; ++j){
char ch = word[j];
for(int k = 'a'; k <= 'z'; ++k){
if(k == ch)
continue;
word[j] = k;
if(q2.count(word))
return step+;
if(dict.count(word) == )
continue;
q.insert(word);
dict.erase(word);
}
word[j] = ch;
}
}
swap(q, q1);
}
return ;
}
};

Java

class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> dict = new HashSet<>(wordList);
if(!dict.contains(endWord))
return 0;
Queue<String> q = new ArrayDeque<>();
q.offer(beginWord);
int l = beginWord.length();
int step = 0;
while(!q.isEmpty()){
step++;
int len = q.size();
for(int i = 0; i < len; ++i){
//String word = q.poll();
StringBuilder word = new StringBuilder(q.poll());
for(int j = 0; j < l; ++j){
char ch = word.charAt(j);
for(int k = 'a'; k < 'z'; ++k){
if(ch == k)
continue;
word.setCharAt(j, (char)k);
String w = word.toString();
if(w.equals(endWord))
return step+1;
if(!dict.contains(w))
continue;
q.offer(w);
dict.remove(w);
}
word.setCharAt(j, ch);
}
}
}
return 0;
}
}
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Set<String> dict = new HashSet<>(wordList);
if(!dict.contains(endWord))
return 0;
Set<String> q1 = new HashSet<>();
q1.add(beginWord);
Set<String> q2 = new HashSet<>();
q2.add(endWord);
int l = beginWord.length();
int step = 0;
while(!q1.isEmpty() && !q2.isEmpty()){
step++;
if(q1.size() > q2.size()){
Set<String> temp = q1;
q1 = q2;
q2 = temp;
}
Set<String> q = new HashSet<>();
for(String s:q1){
StringBuilder str = new StringBuilder(s);
for(int i = 0; i < l; ++i){
char ch = str.charAt(i);
for(int j = 'a'; j <= 'z'; ++j){
if(ch == j)
continue;
str.setCharAt(i, (char)j);
String word = str.toString();
if (q2.contains(word))
return step + 1;
if(!dict.contains(word))
continue;
dict.remove(word);
q.add(word);
}
str.setCharAt(i, ch);
}
}
q1.clear();
q1.addAll(q);
}
return 0;
}
}

LeetCode 127. Word Ladder 单词接龙(C++/Java)的更多相关文章

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

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

  2. [LeetCode] 127. Word Ladder 单词阶梯

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

  3. 127 Word Ladder 单词接龙

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

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

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

  5. Leetcode#127 Word Ladder

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

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

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

  7. leetcode 127. Word Ladder ----- java

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

  8. [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 ...

  9. Java for LeetCode 127 Word Ladder

    Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformatio ...

随机推荐

  1. iOS - 创建可以在 InterfaceBuilder 中实时预览的自定义控件

    一.需求实现一个前后带图标的输入框 这是一个简单的自定义控件,很容易想到自定义一个视图(UIView),然后前后的图标使用 UIImageView 或者 UIButton 显示,中间放一个 UITex ...

  2. 【转】[ppurl]从”皮皮书屋”下载电子书的姿势

    转:http://blog.csdn.net/hcbbt/article/details/42072545 写在前面的扯皮 为什么标题的”皮皮书屋”加上了引号,因为皮皮书屋(http://www.pp ...

  3. Fabric1.4:Go 链码开发与编写

    1 链码结构 1.1 链码接口 链码启动必须通过调用 shim 包中的 Start 函数,传递一个类型为 Chaincode 的参数,该参数是一个接口类型,有两个重要的函数 Init 与 Invoke ...

  4. pc和H5响应式方案

    pc响应式:(所有应用在pc端) 解决方案1.媒体查询 2.flex,百分比  3.栅格布局 媒体查询 @media screen and (max-width:768px) @media scree ...

  5. react入门(六):状态提升&context上下文小白速懂

    一.状态提升 使用 react 经常会遇到几个组件需要共用状态数据的情况.这种情况下,我们最好将这部分共享的状态提升至他们最近的父组件当中进行管理. 原理:父组件基于属性把自己的一个fn函数传递给子组 ...

  6. Golang最强大的访问控制框架casbin全解析

    Golang最强大的访问控制框架casbin全解析 Casbin是一个强大的.高效的开源访问控制框架,其权限管理机制支持多种访问控制模型.目前这个框架的生态已经发展的越来越好了.提供了各种语言的类库, ...

  7. 数据量不足,MedicalNet 如何助力医疗影像 AI 突破瓶颈?

    ​导读 |近日,云+社区技术沙龙“腾讯开源技术”圆满落幕.本次沙龙邀请了多位腾讯技术专家,深度揭秘了腾讯开源项目TencentOS tiny.TubeMQ.Kona JDK.TARS以及Medical ...

  8. 通过核心API启动单个或多个scrapy爬虫

    1. 可以使用API从脚本运行Scrapy,而不是运行Scrapy的典型方法scrapy crawl:Scrapy是基于Twisted异步网络库构建的,因此需要在Twisted容器内运行它,可以通过两 ...

  9. dfs - 概率

    C. Journey time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  10. Web测试中定位bug的方法

    在web测试过程中,经常会遇到页面中内容或数据显示错误,甚至不显示,第一反应就是BUG,没错,确实是BUG.进一步了解这个BUG的问题出在那里,是测试人员需要掌握的,可以简单的使用浏览器自带开发者工具 ...