题目链接

Leetcode.126 单词接龙 II

题目描述

按字典 wordList完成从单词 beginWord到单词 endWord转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> ... -> sk这样的单词序列,并满足:

每对相邻的单词之间仅有单个字母不同

转换过程中的每个单词 s i ( 1 < = i < = k ) s_i(1 <= i <= k) si​(1<=i<=k)必须是字典 wordList 中的单词。注意,beginWord不必是字典 wordList中的单词。
s k = = e n d W o r d s_k == endWord sk​==endWord

给你两个单词 beginWordendWord,以及一个字典 wordList。请你找出并返回所有从 beginWordendWord 的 最短转换序列 ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表 [ b e g i n W o r d , s 1 , s 2 , . . . , s k ] [beginWord, s_1, s_2, ..., s_k] [beginWord,s1​,s2​,...,sk​] 的形式返回。

示例 1:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:[[“hit”,“hot”,“dot”,“dog”,“cog”],[“hit”,“hot”,“lot”,“log”,“cog”]]
解释:存在 2 种最短的转换序列:
“hit” -> “hot” -> “dot” -> “dog” -> “cog”
“hit” -> “hot” -> “lot” -> “log” -> “cog”

示例 2:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出:[]
解释:endWord “cog” 不在字典 wordList 中,所以不存在符合要求的转换序列。

提示:

  • 1 < = b e g i n W o r d . l e n g t h < = 5 1 <= beginWord.length <= 5 1<=beginWord.length<=5
  • e n d W o r d . l e n g t h = = b e g i n W o r d . l e n g t h endWord.length == beginWord.length endWord.length==beginWord.length
  • 1 < = w o r d L i s t . l e n g t h < = 500 1 <= wordList.length <= 500 1<=wordList.length<=500
  • w o r d L i s t [ i ] . l e n g t h = = b e g i n W o r d . l e n g t h wordList[i].length == beginWord.length wordList[i].length==beginWord.length
  • b e g i n W o r d 、 e n d W o r d 和 w o r d L i s t [ i ] beginWord、endWord 和 wordList[i] beginWord、endWord和wordList[i] 由小写英文字母组成
  • b e g i n W o r d ! = e n d W o r d beginWord != endWord beginWord!=endWord
  • w o r d L i s t wordList wordList 中的所有单词 互不相同

分析:

本题在 127. 单词接龙 的基础之上,还要记录最短的路径,求所有的最短路径。

一般这种 求一些路径 我们可以使用 回溯 来解决。

如图,我们要求 起点hit终点cog 的最短路径。



思路:

  • 先用一个哈希表 uset 记录所有的单词
  • 用一个列表 path 记录路径,合法的 在uset中的单词 才插入到path中。
  • 如果遍历到的 当前字符串 c u r = = e n d W o r d cur == endWord cur==endWord,说明找到了终点。根据情况将 path 加入到结果列表 res 中:
    • 如果此时的 path.size() < min_d(初始化为无穷大,用来记录最短路径的长度的),说明又找到了一条更短的路径,所以之前记录在 res 中的路径全部清空,再加入path 同时 min_d 更新为 path.size()。
    • 如果此时的 path.size() == min_d,说明又找到一条相同长度的最短路径,此时将path 直接加入 res即可。

代码:

class Solution {public://记录 wordList 中的单词unordered_set<string> uset;//记录结果路径vector<vector<string>> res;//最短路径长度int min_d = 1e9;void dfs(string cur,string endWord,vector<string>& path,unordered_set<string>& visited){if(cur == endWord){int len = path.size();if(len < min_d){min_d = len;res.clear();res.push_back(path);}else if(len == min_d) res.push_back(path);return ;}//此时path.size() > min_d,说明此时的path中肯定不是最短路径 直接返回即可if(path.size() > min_d) return ;int n = cur.size();//从 cur 的每一个位置,都从 'a' 到 'z' 枚举for(int i = 0;i < n;i++){char op = cur[i];for(char c = 'a';c <= 'z';c++){//如果 c 与 原字符 op 一样 直接跳过本次循环if(op == c) continue;cur[i] = c;if(uset.count(cur)){//如果已经访问过这个点 也直接跳过本次循环if(visited.count(cur)) continue;//记录新的点visited.insert(cur);path.push_back(cur);dfs(cur,endWord,path,visited);//回溯 恢复现场visited.erase(cur);path.pop_back();}}cur[i] = op;}}vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {unordered_set<string> visited;vector<string> path;for(auto &s:wordList) uset.insert(s);//如果 wordList 不包含 endWord 直接返回空列表if(!uset.count(endWord)) return res;//path 此时先加入起点path.push_back(beginWord);//因为是无向图 所以用一个哈希表来记录 已经访问过的点visited.insert(beginWord);dfs(beginWord,endWord,path,visited);return res;}
};

但是这份代码会超时。。。

解法二:

  • 我们可以先通过 BFS,建出一个最短路径的反向图(因为本质上我们是在求 图的最短路问题,而且因为反向图比较好建)。

建好的图应该是以下这个样子:

  • 所以我们第二步只需要从终点到起点 DFS 即可。

代码:

class Solution {public://记录结果vector<vector<string>> res;//图unordered_map<string,vector<string>> g;vector<string> path;string t;void dfs(string u){if(u == t){//因为从终点到起点 所以我们要逆序加入结果列表res.emplace_back(path.rbegin(),path.rend());return;}for(auto &v:g[u]){path.push_back(v);dfs(v);//回溯 恢复现场path.pop_back();}}vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {//记录从起点开始的长度unordered_map<string,int> dist;//记录 wordList 的单词unordered_set<string> uset(wordList.begin(),wordList.end());queue<string> q;//起点距离为0dist[beginWord] = 0;q.push(beginWord);while(!q.empty()){auto cur = q.front();q.pop();auto next_str = cur;int n = cur.size();for(int i = 0;i < n;i++){char op = next_str[i];for(char c = 'a';c <= 'z';c++){if(c == op) continue;next_str[i] = c;if((uset.count(next_str)) && (!dist.count(next_str) || dist[next_str] == dist[cur] + 1)){//建反向边g[next_str].push_back(cur);}//点 s 是没有访问过的点if(uset.count(next_str) && !dist.count(next_str)){dist[next_str] = dist[cur] + 1;//如果 next_str 是终点,直接跳出循环if(next_str == endWord) break;q.push(next_str);}}next_str[i] = op;}}//判断从起点能否到达终点 不能直接返回空列表if(!dist.count(endWord)) return res;//path 加入终点 倒着 dfspath.push_back(endWord);t = beginWord;dfs(endWord);return res;}
};

Leetcode.126 单词接龙 II相关推荐

  1. LeetCode 126. 单词接龙 II(图的BFS)

    1. 题目 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列. 转换需遵循如下规则: 每次转换只能 ...

  2. leetcode 126. 单词接龙 II

    leetcode 126题 介绍 方法一 代码 Solution.java Test.java 方法二 算法介绍 在这个过程中需要注意的问题 代码 Solution.java Test.java 介绍 ...

  3. LeetCode 126 单词接龙 II

    题目描述 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则:每次转换只能改变一 ...

  4. LeetCode——126. 单词接龙 II

    概述 题目地址 题目不难理解,这里不需要额外解释 思路 首先 题目要求寻找最短转换序列,那么我们容易想到使用BFS BFS思路这里不再介绍 沿着BFS考虑代码编写,问题在于如何正确保存获取目标单词的路 ...

  5. 126. 单词接龙 II

    给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: 每次转换只能改变一个字母. ...

  6. 2021-06-14(126. 单词接龙 II)

    class Solution {public List<List<String>> findLadders(String beginWord, String endWord, ...

  7. LeetCode 127. 单词接龙(图的BFS/双向BFS)

    文章目录 1. 题目 2. 图的BFS解题 2.1 单向BFS 2.2 双向BFS !厉害了 1. 题目 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord ...

  8. 【每日刷题】单词接龙II

    题目地址 https://leetcode-cn.com/problems/word-ladder-ii/ 题目描述:单词接龙II 给定两个单词(beginWord 和 endWord)和一个字典 w ...

  9. Java实现 LeetCode 127 单词接龙

    127. 单词接龙 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字 ...

最新文章

  1. 汇编call指令详解_我也能写出雷军的的代码吗?最好的汇编语言入门教程在这里!...
  2. python中删除字典中所有元素的函数_在python中,按值删除字典项的最佳方法是什么?...
  3. 【机器视觉】 par_join算子
  4. “工业4.0”下的可视化工厂建设方案
  5. 中国胎儿(分娩和分娩)和新生儿护理设备行业市场供需与战略研究报告
  6. 深入解析 Flink 的算子链机制
  7. 构建贝叶斯深度学习分类器
  8. 理解numpy dot函数
  9. gsonformat java代码_GSONFormat的简单使用
  10. 全国省市县名称以及区号邮编大全
  11. Ubuntu 部署 Flask + WSGI + Nginx 详解
  12. 6-1 哈夫曼树及哈夫曼编码分数
  13. 一个简单的UDP回显服务器
  14. 还有比元宇宙更牛的商业模式吗?
  15. 2022-2028全球与中国商用车辆HMI解决方案市场现状及未来发展趋势
  16. 量化投资学习——关于XTP交易柜台
  17. 前端生成二维码及把页面转为图片保存到本地
  18. 炫酷黑色系北漂鱼引导页源码
  19. 干货|app自动化测试之Appium 原理 与 JsonWP 协议分析
  20. 塑壳断路器用考虑启动电流么_塑壳断路器的选用

热门文章

  1. PS教程:多边形套索工具
  2. 三个臭皮匠浅谈xss获取用户cookie的安全漏洞
  3. STATA:陈强教授 计量经济学及stata应用第四章 一元线性回归
  4. Python 如何截取截取字符串(字符串切片)
  5. 怎样寻找最佳爱人:一个微积分求解的离散数学问题
  6. PCB板的线宽、覆铜厚度与通过电流对应的关系
  7. Linux下安装.run文件
  8. 毕业论文的论文致谢与编写
  9. 国产00后“蜜桃”女孩!可盐可甜可柔可刚,你喜欢的样子她都有!
  10. 计算机网络应用是什么专业类别,网络工程专业属于什么类别