题目:

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) 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 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)的更多相关文章

  1. [LeetCode] 126. Word Ladder II 词语阶梯 II

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  2. Java for LeetCode 126 Word Ladder II 【HARD】

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  3. [LeetCode] 126. Word Ladder II 词语阶梯之二

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  4. leetcode 126. Word Ladder II ----- java

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  5. Leetcode#126 Word Ladder II

    原题地址 既然是求最短路径,可以考虑动归或广搜.这道题对字典直接进行动归是不现实的,因为字典里的单词非常多.只能选择广搜了. 思路也非常直观,从start或end开始,不断加入所有可到达的单词,直到最 ...

  6. leetcode@ [126] Word Ladder II (BFS + 层次遍历 + DFS)

    https://leetcode.com/problems/word-ladder-ii/ Given two words (beginWord and endWord), and a diction ...

  7. 127. 126. Word Ladder *HARD* -- 单词每次变一个字母转换成另一个单词

    127. Given two words (beginWord and endWord), and a dictionary's word list, find the length of short ...

  8. [LeetCode] 127. Word Ladder 单词阶梯

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...

  9. leetcode 127. Word Ladder、126. Word Ladder II

    127. Word Ladder 这道题使用bfs来解决,每次将满足要求的变换单词加入队列中. wordSet用来记录当前词典中的单词,做一个单词变换生成一个新单词,都需要判断这个单词是否在词典中,不 ...

随机推荐

  1. Maven 基础(二) | 解决依赖冲突的正确姿势

    一.依赖原则 假设,在 JavaMavenService2 模块中,log4j 的版本是 1.2.7,在 JavaMavenService1 模块中,它虽然继承于 JavaMavenService2 ...

  2. MADP(移动应用开发平台)推动企业数字化转型

    移动互联网时代,企业对于移动应用程序的需求呈现爆炸式增长,移动解决方案供应商一直致力于寻找解决方案帮助企业完成这些移动集成需求,MADP(移动应用开发平台)因此产生,MADP允许提供一种解决方案,可以 ...

  3. UIChatBox模块示例demo

    感谢论坛版主 马浩川 的分享. UIChatBox 模块是一个聊天输入框模块,开发者可自定义该输入框的功能.通过 open 接口可在当前 window 底部打开一个输入框,该输入框的生命属于当前 wi ...

  4. flask部署深度学习模型

    flask部署深度学习模型 作为著名Python web框架之一的Flask,具有简单轻量.灵活.扩展丰富且上手难度低的特点,因此成为了机器学习和深度学习模型上线跑定时任务,提供API的首选框架. 众 ...

  5. 区间 dp

    以一个经典题目引入到正题 : 有 n 堆石子 , 每两堆石子合并会花费一定的价值,所花费的价值即为 两堆石子上的价值和 , 问合并所有的石子后的最小花费 ? 思路分析 : 因为题干可以看成是对每个区间 ...

  6. Maven 基础环境搭建 项目依赖jar包导入

    一.创建一个Maven工程 不清楚的话请查阅其它文档. 二.引入项目依赖的jar包 1.Spring 2.SpringMvc 3.Mybatis 4. 数据库连接池,驱动 5.其它(jstl.serv ...

  7. 一张图快速上手Xmind思维导图

    使用软件:Xmind8 pro版(可在网上找破解版),应用广泛,功能强大

  8. Linux中两个重要的基础服务

    本文服务器基于centos7,客户端Windows10 FTP FTP(File Transfer Protocol),文件传输协议,是一个比较古老的基于TCP,用于不同计算机间传递文件的协议. 安装 ...

  9. 【WPF学习】第十三章 理解路由事件

    每个.NET开发人员都熟悉“事件”的思想——当有意义的事情发生时,由对象(如WPF元素)发送的用于通知代码的消息.WPF通过事件路由(event routing)的概念增强了.NET事件模型.事件路由 ...

  10. Java Web面试题整理(思维导图)

    1,动态网站技术有哪些? 2,一般的Web架构是指BS 还是CS,BS架构是什么咚咚? 3,Web应用程序的流程,即把一个URL串输入地址栏后发生写什么? 4,说一说Servlet生命周期? 5,在W ...