题目:

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. linux下卸载旧版本cmake安装新版本cmake

    1.看当前cmake版本 cmake --version 2.卸载旧版本下的cmake apt-get autoremove cmake 3.安装新版面cmake http://www.cnblogs ...

  2. Docker系列-第五篇Docker容器数据卷

    1.是什么 在生产环境中使用 Docker,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作 . 容器中的管理数据主要有两种方式 : 数据卷 ( Data V ...

  3. Java扫描指定文件路径下的文件并且递归扫描其子目录下的所有文件

    本文主要实现了扫描指定文件路径下的文件,递归扫描其子目录下的所有文件信息,示例文件为: 要求将后缀为.dat的文件夹信息也写入到数据库中,然后将.chk文件解析,将文件中对应的内容读出来写入到数据库, ...

  4. LinkedHashMap与HashMap的使用比较

    现在由于项目需要,使用了LinkedHashMap,一开始由于很少用到Map,然后就直接使用了HashMap,在将数据成功存入之后取出来就出了问题,数据输出顺序没有按预期顺序输出,现在先看代码: 文件 ...

  5. json中含有换行符'\r','\n'的处理

    一.josn简易说明  json是一种轻量级的数据交换格式,是一系列格式字符串.在数据交换中,经常会使用到,具有易读性,轻量级.很多地方会使用到,用处广泛.如下:(截取的一段json体) " ...

  6. 讨论Java中的内部类是什么?

    目录 前言 what is that? 成员内部类 局部内部类 匿名内部类 why use it? how to use? 前言 内部类,讲完前面的特性,今天就讲下内部类这个用的比较多,出现频率挺高的 ...

  7. 使用Jenkins进行前端UVE项目部署

    操作步骤 1.用 Jenkins 管理员账号下载 NodeJS Plugin 2.系统管理 ---> 全局工具配置 ---> NodeJS ---> 安装 ---> 自动安装 ...

  8. PTA - 堆栈模拟队列

    设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q. 所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数: int IsFull(Stack S):判断堆栈S是否已满,返回1或0: in ...

  9. Flash 上下文管理

    1.Local() 作用:为每个协程或线程创建一个独立的内存空间 储存格式: { 唯一标识: {'stack': []} } 代码 try: from greenlet import getcurre ...

  10. informatica9.5.1后最一步出错(ICMD_10033,INFACMD_10053)

    错误信息: OutPut : [ICMD_10033] Command [ping] failed with error [[INFACMD_10053] [Domain [Domain_rotkan ...