题目:

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. xshell连接kali linux虚拟机

    这次测试一波三折 刚开始在百度经验看的先修改ssh参数,蓝色的字是百度的,重点都在图片上 1.修改sshd_config文件,命令为: vi /etc/ssh/sshd_config 将#Passwo ...

  2. es6种for循环中let和var区别

    let和var区别: for(var i=0;i<5;i++){ setTimeout(()=>{ console.log(i);//5个5 },100) } console.log(i) ...

  3. Redis系列(一):Redis简介及环境安装

    提到Redis,大家肯定都听过,并且应该都在项目中或多或少的使用过,也许你觉得Redis用起来挺简单的呀,但如果有人问你下面的几个问题(比如同事或者面试官),你能回答的上来吗? 什么是Redis? R ...

  4. 【转】[IT综合面试]牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

    感谢IT面试群 S-北京-陈磊 的整理分享.   基础篇:操作系统.计算机网络.设计模式         提高篇:WIN32.MFC与Linux 算法篇:算法与数据结构           一:操作系 ...

  5. Go 每日一库之 go-flags

    简介 在上一篇文章中,我们介绍了flag库.flag库是用于解析命令行选项的.但是flag有几个缺点: 不显示支持短选项.当然上一篇文章中也提到过可以通过将两个选项共享同一个变量迂回实现,但写起来比较 ...

  6. js 日期增减

    js 的 Date 对象提供了许多方法,可以获取日期的年.月.日等信息,也可以修改年.月.日 日期的增减可以使用setFullYear().setMonth().setDate() 等方法 exp: ...

  7. 76.纯 CSS 创作一组单元素办公用品

    原文地址:https://segmentfault.com/a/1190000015607676 学习后效果地址:https://scrimba.com/c/c8PQ3PTB 感想:利用css的制图. ...

  8. influxdb的命令们

    InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据.而InfluxDB自带的各种特殊函数如求标准差,随机取样数据,统计数据变化比等,使数据统计 ...

  9. Knative 简介

    原文地址:https://yq.aliyun.com/articles/658800

  10. Python通过win32 com接口实现offic自动化

    最近几天通过Python做一些自动生成office报表的东东,比如解析.xml文件,导出.html/WORD/PPT等格式,html不足一提,只需要简单的html静态网页知识即可,这儿要说的是怎么生成 ...