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用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...
随机推荐
- FastOne专业计算平台助力生命科学研发
11月16日,由AWS主办的云计算行业沙龙在中油阳光酒店举行,速石科技CEO陈熹就高性能计算如何助力生命科学领域发表了精彩的演讲. 面临的问题及挑战 在算力及高性能领域,随着行业客户的业务需求量,数据 ...
- 集合下篇—Map和Set 源码分析
Map Map不同于Collection集合,Map存放的是键值对,且键不能重复 1 .HashMap (底层是哈希表,Java中用链表的数组实现,存取顺序不一致) 这篇博客主要讲集合的,哈希表这样的 ...
- Docker 学习 1 入门
Docker 学习 1 入门 dockert 安装. Mac Ubuntu 查看docker 版本 docker version 拉取image. docker pull e.g docker pul ...
- 打包一份py给大家用!!!
好不容易写完了代码,却发现对面无法使用自己的python代码,其无奈可想而知 在这里就给大家介绍一下pyinstaller的简单用法 你所需要的就是在电脑上安装好 https://blog.csdn. ...
- LeetCode 858 镜面反射
题目 有一个特殊的正方形房间,每面墙上都有一面镜子.除西南角以外,每个角落都放有一个接受器,编号为 0, 1,以及 2. 正方形房间的墙壁长度为 p,一束激光从西南角射出,首先会与东墙相遇,入射点到接 ...
- Perl语言入门(中文版)(第6版) 东南大学出版社
第一章简介 问题与答案 这本书适合你吗? 为何有这么多的脚注? 关于习题和解答? 习题前标的数字是什么意思? 如果我是Perl讲师? “Perl”这个词表示什么意思? Larry为什么要创造Perl? ...
- equals()和hashCode()使用总结
equals()和hashCode()使用总结 equals() Object类中的equals方法和"=="是一样的,没有区别,即俩个对象的比较是比较他们的栈内存中存储的内存地址 ...
- GC原理---垃圾收集算法
垃圾收集算法 Mark-Sweep(标记-清除算法) 标记清除算法分为两个阶段,标记阶段和清除阶段.标记阶段任务是标记出所有需要回收的对象,清除阶段就是清除被标记对象的空间. 优缺点:实现简单,容易产 ...
- Java框架-MyBatis三剑客之MyBatis Generator(mybatis-generator MBG插件)详解
生成器设计思路: 连接数据库 -> 获取表结构 -> 生成文件 1 下载与安装 官网文档入口 最方便的 maven 插件使用方式 贴至pom 文件 2 新建配置文件 填充配置信息(官网示例 ...
- android之Activity的创建与关闭
Activity的启动和关闭 1.启动activity activity的启动分为两种,一种为入口activity,另一种为其他activity 在AndroidManifests进行配置,入口act ...