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用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...
随机推荐
- forkjoin及其性能分析,是否比for循环快?
最近看了网上的某公开课,其中有讲到forkjoin框架.在这之前,我丝毫没听说过这个东西,很好奇是什么东东.于是,就顺道研究了一番. 总感觉这个东西,用的地方很少,也有可能是我才疏学浅.好吧,反正问了 ...
- Spring Boot2 系列教程 (六) | 使用 JdbcTemplates 访问 Mysql
前言 如题,今天介绍 springboot 通过jdbc访问关系型mysql,通过 spring 的 JdbcTemplate 去访问. 准备工作 SpringBoot 2.x jdk 1.8 mav ...
- Ubuntu18.04 一次性升级Python所有库
pip是什么 pip 是 Python 包管理工具,该工具提供了对Python 包的查找.下载.安装.卸载的功能. 升级pip版本 默认Ubuntu自带的pip (pip 9.0.1)是基于Pytho ...
- web网页设计五种布局
1.大框套小框布局 2.通栏布局 3.导航栏在主视觉下方的布局 4.左中右布局 5.环绕式布局
- AttributeError: 'Table' object has no attribute 'plot'错误
今天在用到camelot爬取pdf的表格时,想选取部分区域进行爬取,就想用plot把pdf画一下,选个坐标. 看了网上的示例,在使用camelot.read_pdf获取当前页面以后调用tables[0 ...
- angular 构建可以动态挂载的配置服务
angular 构建可以动态挂载的配置服务 Intro 在 angular 中可以指定 environment 来区分不同环境下的配置,然而 environment 中的配置会在打包时是固定的,想要像 ...
- [bzoj2815] [洛谷P2597] [ZJOI2012] 灾难
Description 阿米巴是小强的好朋友. 阿米巴和小强在草原上捉蚂蚱.小强突然想,如果蚂蚱被他们捉灭绝了,那么吃蚂蚱的小鸟就会饿死,而捕食小鸟的猛禽也会跟着灭绝,从而引发一系列的生态灾难. 学过 ...
- 玩转Django2.0---Django笔记建站基础四(视图)
第四章 视图 4.1 探究视图 一.视图说明 视图(View)是Django的MTV架构模式的V部分,主要负责处理用户请求和生成相应的相应部分,然后在页面或其它类型文档中显示.也可以理解为视图是MVC ...
- Cobalt_Strike扩展插件
Cobalt_Strike3.14下载: https://download.csdn.net/download/weixin_41082546/11604021 https://github.com/ ...
- Spring AOP源码分析--代理方式的选择
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 年前写了一个面试突击系列的文章,目前只有redis相关的.在这个系列里,我整理了一些面试题与大家 ...