LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)
题目:
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) 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 an empty list 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:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Example 2:
Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"] Output: [] Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
分析:
这道题是LeetCode 127. Word Ladder 单词接龙(C++/Java)的扩展,要找出所有最短转换序列。
还是利用BFS,在每一次搜索的时候都要将单词之间的转换记录下来,利用map进行存储,例如
["hot","dot","dog","lot","log","cog"]
hot可以改变一个字符转换为dot和lot,可以将单词和由这个单词扩展的单词列表存进map中,方便我们后续来进行路径构建。
此外我们要在每一层搜索前将单词从由单词序列构建的字典中删除掉,而不是在找到一个单词就删除。而且有的单词可能会成为多个单词的扩展,例如hot和dot都可以扩展为lot,所以如果当前循环中没有找到结果,所有有可能构建路径的单词都要存进map中,在这一轮搜索完毕后,再将它们从字典中删除。
程序:
C++
class Solution {
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict;
vector<vector<string>> res;
for(string s:wordList)
dict.insert(s);
if(!dict.count(endWord))
return {};
dict.erase(endWord);
unordered_set<string> p{beginWord}, q;
unordered_map<string, vector<string>> children;
int l = beginWord.length();
bool find = false;
while(!p.empty() && !find){
for(string s:p)
dict.erase(s);
for(string str:p){
string word = str;
for(int i = ; i < l; ++i){
char ch = word[i];
for(int j = 'a'; j < 'z'; ++j){
if(ch == j)
continue;
word[i] = j;
if(word == endWord){
find = true;
children[str].push_back(word);
}else{
if(dict.count(word) && !find){
q.insert(word);
children[str].push_back(word);
}
}
}
word[i] = ch;
}
}
p.clear();
swap(p, q);
}
if(find){
vector<string> path{beginWord};
bfs(res, children, path, beginWord,endWord);
}
return res;
}
private:
void bfs(vector<vector<string>> &res,
unordered_map<string, vector<string>> &children,
vector<string> path,
string beginWord, string endWord){
if(beginWord == endWord){
res.push_back(path);
return;
}
auto it = children.find(beginWord);
if(it == children.end()) return;
for(string word:it->second){
path.push_back(word);
bfs(res, children, path, word, endWord);
path.pop_back();
}
}
};
Java
class Solution {
public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
Set<String> dict = new HashSet<>(wordList);
List<List<String>> res = new ArrayList<>();
if(!dict.contains(endWord))
return res;
Set<String> p = new HashSet<>();
p.add(beginWord);
int l = beginWord.length();
HashMap<String, List<String>> children = new HashMap<>();
boolean find = false;
while(!p.isEmpty() && !find){
for(String s:p)
dict.remove(s);
Set<String> q = new HashSet<>();
for(String str:p){
char[] word = str.toCharArray();
for(int i = 0; i < l; ++i){
char ch = word[i];
for(int j = 'a'; j <= 'z'; ++j){
if(j == ch)
continue;
word[i] = (char)j;
String w = new String(word);
if(w.equals(endWord)){
find = true;
List<String> list = children.getOrDefault(str, new ArrayList<>());
list.add(w);
children.put(str, list);
}else{
if(dict.contains(w) && !find){
List<String> list = children.getOrDefault(str, new ArrayList<>());
list.add(w);
children.put(str, list);
q.add(w);
}
}
}
word[i] = ch;
}
}
p = q;
}
if(find){
List<String> path = new ArrayList<>();
path.add(beginWord);
bfs(res, path, children, beginWord, endWord);
}
return res;
}
private void bfs(List<List<String>> res,
List<String> path,
HashMap<String, List<String>> children,
String beginWord, String endWord){
if(beginWord.equals(endWord)){
res.add(new ArrayList(path));
return;
}
if(!children.containsKey(beginWord))
return;
List<String> list = children.get(beginWord);
for(String word:list){
path.add(word);
bfs(res, path, children, word, endWord);
path.remove(word);
}
}
}
LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)的更多相关文章
- [LeetCode] 126. Word Ladder II 词语阶梯 II
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- Java for LeetCode 126 Word Ladder II 【HARD】
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...
- [LeetCode] 126. Word Ladder II 词语阶梯之二
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- leetcode 126. Word Ladder II ----- java
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- Leetcode#126 Word Ladder II
原题地址 既然是求最短路径,可以考虑动归或广搜.这道题对字典直接进行动归是不现实的,因为字典里的单词非常多.只能选择广搜了. 思路也非常直观,从start或end开始,不断加入所有可到达的单词,直到最 ...
- leetcode@ [126] Word Ladder II (BFS + 层次遍历 + DFS)
https://leetcode.com/problems/word-ladder-ii/ Given two words (beginWord and endWord), and a diction ...
- 127. 126. Word Ladder *HARD* -- 单词每次变一个字母转换成另一个单词
127. Given two words (beginWord and endWord), and a dictionary's word list, find the length of short ...
- [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用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...
随机推荐
- 关于revit的外部扩展存储
最近被revit的外部扩展存储搞得死去活来,作为日后再次使用的预防针,此处随手留下印记,以作警示. 首先我们知道外部扩展存储ExtensibleStorage是revit提供给revit二次开发人员用 ...
- Scala实践13
1.隐式参数 方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记.如果该参数列表中的参数没有像往常一样传递,Scala将查看它是否可以获得正确类型的隐式值,如果可以,则自动传递. S ...
- Frogger POJ - 2253(求两个石头之间”所有通路中最长边中“的最小边)
题意 题目主要说的是,有两只青蛙,在两个石头上,他们之间也有一些石头,一只青蛙要想到达另一只青蛙所在地方,必须跳在石头上.题目中给出了两只青蛙的初始位置,以及剩余石头的位置,问一只青蛙到达另一只青 ...
- 开源项目SMSS开源项目(三)——protobuf协议设计
本文的第一部分将介绍protobuf使用基础以及如何利用protobuf设计通信协议.第二部分会给出smss项目的协议设计规范和源码讲解. 一.Protobuf使用基础 什么是protobuf pro ...
- 《即时消息技术剖析与实战》学习笔记8——IM系统如何保证长连接的可用性:心跳机制
假设有以下突发意外情况: 用户进入信号不好的地方,手机没有网络信号了 上网的路由器突然掉线了 这个时候,比如微信发消息,消息就会转圈圈,甚至变成红色叹号-- 上面情况都会导致"长连接&quo ...
- MySql配置环境变量
完成后安装好MySQL,为MySQL配置环境变量. 0)在我的电脑上点击右键选择属性-->高级系统设置-->环境变量1)新建MYSQL_HOME变量,并配置:D:\Develop\mysq ...
- 字符串(String)的创建,以及字符串的属性及方法
1.String对象的创建 方法1: var txt = new String("i am String"); console.log(txt); // 结果为:i am Stri ...
- Docker基础内容之数据持久化
数据卷的特性 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS 数据卷可以在容器之间共享和重用,相当于将一个分区挂载到多个目录下面 数据卷内容的修改会立马生效 数据卷的更新,不会影响镜像: ...
- Ubuntu通过终端命令行换阿里源
检查Ubuntu系统的Codename $ lsb_release -a 得到结果: No LSB modules are available. Distributor ID: Ubuntu Desc ...
- ActiveMQ 快速入门教程系列 第一章 点对点消息实现
ActiveMQ 开发包下载及运行环境搭建 主页:http://activemq.apache.org/目前最新版本:5.11.1开发包及源码下载地址:http://activemq.apache.o ...