题目:

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. Sample Code之Take a screenshot of a SceneView

    周末事情太多了,以后就工作日发布随笔吧.周末的话,看心情,也许也会发~ 今天的实例代码解析是Take a screenshot of a SceneView,也就是获取快照,话不多说,进入正题. 首先 ...

  2. 在A卡下的 Matlab 运行C/C++混编的GPU程序

    首先将你的.MEX文件和matlab脚本放在一个文件夹下开始运行 如果出错查看是那个.MEX文件出错 用depends这个软件查看他的依赖dll文件下载对应文件 放到当前文件夹下,运行成功.

  3. Spring学习记录1——IoC容器

    IoC容器 1.1  IoC概述 Ioc(Inverse of Control,控制反转)是Spring容器的内核.对于软件来说,即某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定,即由 ...

  4. 盘一盘Tidyverse| 筛行选列之select,玩转列操作

    原文链接:https://mp.weixin.qq.com/s/ldO0rm3UM_rqlFnU3euYaA 2020年,开封 <R 数据科学>R for data science,系统学 ...

  5. Java单体应用 - 导读

    原文地址:http://www.work100.net/training/monolithic 更多教程:光束云 - 免费课程 Java单体应用 本阶段课程将学习如何进行Java单体Web应用开发,经 ...

  6. PHP——foreach

    一.foreach 在PHP中foreach循环语句,常用于遍历数组,一般有两种使用方式:不取下标.取下标 (一)只取值,不取下标 <?php foreach (数组 as 值){ //执行的任 ...

  7. 【Docker】 windows10 docker 使用

    原文地址:https://www.aliyun.com/jiaocheng/872144.html 摘要:docker之前在Windows和MacOS上的版本都是通过Linux虚拟机的形式,而现在Do ...

  8. python+autoit用法

    一.自己封装的一些使用到的autoit库 import autoit class MouseControl(object): ''' AutoIt鼠标相关操作 ''' def __init__(sel ...

  9. JAVA WebSocket 使用时需要注意的地方

    最近在做一个项目,需要用WebSocket与另外一个平台建立通讯,来获取项目业务需要的实时数据,因此项目一启动,后台就要与另外一个平台建立WebSocket连接并且要保证他们的之间有且只有一条持续畅通 ...

  10. ThreeJS 物理材质shader源码分析(像素着色器)

    再此之前推荐一款GLTF物理材质在线编辑器https://tinygltf.xyz/ 像素着色器(meshphysical_frag.glsl) #define PHYSICAL uniform ve ...