当前位置: 首页 > news >正文

126. 单词接龙 II

题目

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

  • 每对相邻的单词之间仅有单个字母不同。
  • 转换过程中的每个单词 si1 <= i <= k)必须是字典 wordList 中的单词。注意,beginWord 不必是字典 wordList 中的单词。
  • sk == endWord

给你两个单词 beginWord 和 endWord ,以及一个字典 wordList 。请你找出并返回所有从 beginWord 到 endWord 的 最短转换序列 ,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表 [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 <= beginWord.length <= 5
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 500
  • wordList[i].length == beginWord.length
  • beginWordendWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有单词 互不相同

思路

        首先把字典存起来方便查找,如果目标单词不在字典里,就直接结束,然后先用广度优先搜索,从起始单词开始,逐层尝试改变每个位置的字母,看新单词是否在字典里。在这个过程中,把已用过的单词从字典去掉,避免重复,同时,构建一个反向图,记录每个符合条件的新单词是由哪个旧单词变来的。一旦找到目标单词,就不再继续扩展。 当bfs找到了目标单词,就说明存在最短序列,然后利用深搜和回溯,依据反向图从目标单词反向查找,把经过的单词依次添加到路径中,当回到起始单词时,就找到了一条完整的转换序列。

代码

class Solution {
public:unordered_set<string> dict, curLevel, nextLevel;unordered_map<string, vector<string>> graph;//反向图,存储每个单词的前一个可能的单词deque<string> path;//用于记录当前的转换路径vector<vector<string>> ans;//存储所有从beginWord到endWord的最短转换序列。//初始化函数,将wordList存储到dict中void build(vector<string>& wordList){dict = unordered_set<string>(wordList.begin(), wordList.end());graph.clear();ans.clear();curLevel.clear();nextLevel.clear();}//找到所有从beginWord到endWord的最短转换序列vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {build(wordList);//初始化if (dict.find(endWord) == dict.end()){return ans;}if (bfs(beginWord, endWord))//先调用bfs广搜,找到endword就深搜,找生成路径{dfs(endWord, beginWord);}return ans;}bool bfs(string begin, string end)//广搜从beginWord开始逐层扩展,构建反向图{bool find = false;curLevel.insert(begin);while (!curLevel.empty()){//移除当前层的单词for (const string& word : curLevel){dict.erase(word);//避免重复使用}for (const string& word : curLevel){string w = word;for (int i = 0; i < w.size(); i++){char old = w[i];//每个位置的字符依次替换成a到z,检查替换后的单词是否在dict且不等于原单词for (char ch = 'a'; ch <= 'z'; ch++){w[i] = ch;if (dict.find(w) != dict.end() && w != word){if (w == end) {find = true;}graph[w].push_back(word);nextLevel.insert(w);}}w[i] = old;}}if(find){return true;}else//没找到endword{swap(curLevel, nextLevel);//交换curLevel和nextLevel,继续下一层的扩展nextLevel.clear();}}return false;}//回溯生成路径void dfs(string word, string aim) {path.push_front(word);if(word==aim){ans.push_back(vector<string>(path.begin(), path.end()));}else if (graph.find(word)!=graph.end()){for(const string& next:graph[word]){dfs(next,aim);}}path.pop_front();}
};

http://www.xdnf.cn/news/228943.html

相关文章:

  • 数学建模论文手的学习日常01
  • 牛客:AB5 点击消除
  • 【已解决】TensorRT安装好后加载不了或者转换不了engine模型,或者加载时报错
  • LeetCode392_判断子序列
  • 基于PHP的在线编程课程学习系统
  • [特殊字符] 开发工作高内存占用场景下,Windows 内存压缩机制是否应该启用?实测分析与优化建议
  • 涨薪技术|0到1学会性能测试第44课-apachetop模块监控
  • MCU片上存储器的类型与特性
  • 【学习 python day5】
  • 3.2goweb框架GORM
  • kotlin 过滤 filter 函数的作用和使用场景
  • MATLAB小试牛刀系列(3)
  • linux系统加固
  • 基于 Rancher 部署 Kubernetes 集群的工程实践指南
  • StarRocks Lakehouse 如何重构大数据架构?
  • 基于标注数据的情感分析模型研究
  • 使用 Spring Data Redis 实现 Redis 数据存储详解
  • 【数据结构】——顺序表刷题
  • 论文阅读:2024 EMNLP User Inference Attacks on Large Language Models
  • MySQL表的内外连接
  • 黑群晖Moments视频无缩略图,安装第三方ffmpeg解决
  • kivy android打包buildozer.spec GUI配置
  • (Go Gin)Gin学习笔记(二):路由配置、基本路由、表单参数、上传单个文件、上传多个文件、浅扒路由原理
  • 2025年- H13-Lc121-189.轮转数组(普通数组)---java版
  • Neo4j多关系或多路径
  • 云备份服务器,数据备份服务器的方法有哪些?
  • 嵌入式软件--stm32 DAY 5 USART串口通讯(上)
  • java瘦身、升级graalvm
  • QT6 源(63)篇六:阅读与注释 QString 这个类,包含了 QString 类的 完整源码,也附上 QLatin1String 类的
  • Redis的简单介绍