回溯题目:单词接龙 II
文章目录题目标题和出处难度题目描述要求示例数据范围解法思路和算法代码复杂度分析题目标题和出处标题单词接龙 II出处126. 单词接龙 II难度8 级题目描述要求字典wordList \texttt{wordList}wordList中从开始单词beginWord \texttt{beginWord}beginWord到结束单词endWord \texttt{endWord}endWord的转换序列是一个按下述规格形成的序列beginWord → s 1 → s 2 → … → s k \texttt{beginWord} \rightarrow \texttt{s}_\texttt{1} \rightarrow \texttt{s}_\texttt{2} \rightarrow \ldots \rightarrow \texttt{s}_\texttt{k}beginWord→s1​→s2​→…→sk​每一对相邻的单词只差一个字母。对于1 ≤ i ≤ k \texttt{1} \le \texttt{i} \le \texttt{k}1≤i≤k每个s i \texttt{s}_\texttt{i}si​都在wordList \texttt{wordList}wordList中。注意beginWord \texttt{beginWord}beginWord不需要在wordList \texttt{wordList}wordList中。s k endWord \texttt{s}_\texttt{k} \texttt{endWord}sk​endWord给定两个单词beginWord \texttt{beginWord}beginWord和endWord \texttt{endWord}endWord以及一个字典wordList \texttt{wordList}wordList返回所有从beginWord \texttt{beginWord}beginWord到endWord \texttt{endWord}endWord的最短转换序列。如果不存在这样的转换序列返回空列表。每个序列都应该以单词列表[beginWord, s 1 , s 2 , … , s k ] \texttt{[beginWord, s}_\texttt{1}\texttt{, s}_\texttt{2}\texttt{, }\ldots\texttt{, s}_\texttt{k}\texttt{]}[beginWord, s1​, s2​,…, sk​]的形式返回。示例示例 1输入beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log,cog] \texttt{beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log,cog]}beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log,cog]输出[[hit,hot,dot,dog,cog],[hit,hot,lot,log,cog]] \texttt{[[hit,hot,dot,dog,cog],[hit,hot,lot,log,cog]]}[[hit,hot,dot,dog,cog],[hit,hot,lot,log,cog]]解释存在2 \texttt{2}2种最短的转换序列hit → hot → dot → dog → cog \texttt{hit} \rightarrow \texttt{hot} \rightarrow \texttt{dot} \rightarrow \texttt{dog} \rightarrow \texttt{cog}hit→hot→dot→dog→coghit → hot → lot → log → cog \texttt{hit} \rightarrow \texttt{hot} \rightarrow \texttt{lot} \rightarrow \texttt{log} \rightarrow \texttt{cog}hit→hot→lot→log→cog示例 2输入beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log] \texttt{beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log]}beginWord hit, endWord cog, wordList [hot,dot,dog,lot,log]输出[] \texttt{[]}[]解释结束单词cog \texttt{cog}cog不在字典中所以不存在有效的转换序列。数据范围1 ≤ beginWord.length ≤ 5 \texttt{1} \le \texttt{beginWord.length} \le \texttt{5}1≤beginWord.length≤5endWord.length beginWord.length \texttt{endWord.length} \texttt{beginWord.length}endWord.lengthbeginWord.length1 ≤ wordList.length ≤ 500 \texttt{1} \le \texttt{wordList.length} \le \texttt{500}1≤wordList.length≤500wordList[i].length beginWord.length \texttt{wordList[i].length} \texttt{beginWord.length}wordList[i].lengthbeginWord.lengthbeginWord \texttt{beginWord}beginWord、endWord \texttt{endWord}endWord和wordList[i] \texttt{wordList[i]}wordList[i]由小写英语字母组成beginWord ≠ endWord \texttt{beginWord} \ne \texttt{endWord}beginWordendWordwordList \texttt{wordList}wordList中的所有字符串各不相同所有最短转换序列的长度之和不超过10 5 \texttt{10}^\texttt{5}105解法思路和算法这道题是「单词接龙」的进阶要求计算所有从beginWord \textit{beginWord}beginWord到endWord \textit{endWord}endWord的最短转换序列。需要首先判断转换序列是否存在当转换序列存在时再生成所有的最短转换序列。为了快速判断一个单词是否在字典中需要使用哈希集合存储字典中的每个单词。只有当endWord \textit{endWord}endWord在字典中时才可能存在从beginWord \textit{beginWord}beginWord到endWord \textit{endWord}endWord的转换序列因此首先判断endWord \textit{endWord}endWord是否在字典中如果endWord \textit{endWord}endWord不在字典中则不存在从beginWord \textit{beginWord}beginWord到endWord \textit{endWord}endWord的转换序列返回空列表。以下只考虑endWord \textit{endWord}endWord在字典中的情况。判断转换序列是否存在可以使用广度优先搜索实现当转换序列存在时广度优先搜索可以确保得到最短转换序列。广度优先搜索的过程中需要使用哈希集合存储已访问的单词。初始时将beginWord \textit{beginWord}beginWord添加到已访问的哈希集合将beginWord \textit{beginWord}beginWord入队列。为了生成所有的最短转换序列广度优先搜索的过程中需要记录最短转换序列中的相邻单词之间的关系。具体做法是使用两个哈希表分别记录每个单词所在的层数和每个单词的前驱单词集合两个哈希表分别为层数哈希表和前驱哈希表。规定beginWord \textit{beginWord}beginWord在第1 11层从beginWord \textit{beginWord}beginWord开始遍历每次遍历同一层的全部单词并得到下一层的全部单词。记当前层为level \textit{level}level对于当前层的每个单词word \textit{word}word执行如下操作。如果word endWord \textit{word} \textit{endWord}wordendWord则找到转换序列结束广度优先搜索。如果word ≠ endWord \textit{word} \ne \textit{endWord}wordendWord则执行后续操作。得到word \textit{word}word的所有相邻单词对于每个相邻单词adjacent \textit{adjacent}adjacent执行如下操作。如果adjacent \textit{adjacent}adjacent在层数哈希表中存在且对应层数为level 1 \textit{level} 1level1则adjacent \textit{adjacent}adjacent为word \textit{word}word的后继单词word \textit{word}word为adjacent \textit{adjacent}adjacent的前驱单词将word \textit{word}word添加到adjacent \textit{adjacent}adjacent的前驱单词集合中。否则如果adjacent \textit{adjacent}adjacent在字典中且尚未加入已访问的哈希集合则将adjacent \textit{adjacent}adjacent加入已访问的哈希集合将adjacent \textit{adjacent}adjacent和对应层数level 1 \textit{level} 1level1添加到层数哈希表将word \textit{word}word添加到adjacent \textit{adjacent}adjacent的前驱单词集合中将adjacent \textit{adjacent}adjacent入队列。如果遍历结束仍未发现endWord \textit{endWord}endWord则不存在转换序列。当存在转换序列时从endWord \textit{endWord}endWord开始回溯得到所有的最短转换序列。用word \textit{word}word表示当前单词从前驱哈希表得到word \textit{word}word的所有前驱单词对于每个前驱单词执行回溯每次遇到beginWord \textit{beginWord}beginWord时即得到一个从endWord \textit{endWord}endWord到beginWord \textit{beginWord}beginWord的最短转换序列将该序列反转之后得到一个从beginWord \textit{beginWord}beginWord到endWord \textit{endWord}endWord的最短转换序列。代码classSolution{ListListStringladdersnewArrayListListString();StringbeginWord;intwordLength;MapString,SetStringprevMapnewHashMapString,SetString();ListStringtempnewArrayListString();publicListListStringfindLadders(StringbeginWord,StringendWord,ListStringwordList){SetStringwordSetnewHashSetString();for(Stringword:wordList){wordSet.add(word);}if(!wordSet.contains(endWord)){returnladders;}this.beginWordbeginWord;this.wordLengthbeginWord.length();booleanfoundbfs(beginWord,endWord,wordSet);if(found){backtrack(endWord);}returnladders;}publicbooleanbfs(StringbeginWord,StringendWord,SetStringwordSet){SetStringvisitednewHashSetString();visited.add(beginWord);MapString,IntegerlevelMapnewHashMapString,Integer();levelMap.put(beginWord,1);QueueStringqueuenewArrayDequeString();queue.offer(beginWord);intlevel0;while(!queue.isEmpty()){level;intsizequeue.size();for(inti0;isize;i){Stringwordqueue.poll();if(word.equals(endWord)){returntrue;}ListStringadjacentWordsgetAdjacentWords(word);for(Stringadjacent:adjacentWords){if(levelMap.getOrDefault(adjacent,0)level1){prevMap.get(adjacent).add(word);}elseif(wordSet.contains(adjacent)visited.add(adjacent)){levelMap.put(adjacent,level1);prevMap.put(adjacent,newHashSetString());prevMap.get(adjacent).add(word);queue.offer(adjacent);}}}}returnfalse;}publicListStringgetAdjacentWords(Stringword){ListStringadjacentWordsnewArrayListString();char[]arrword.toCharArray();for(inti0;iwordLength;i){charoriginalarr[i];for(charca;cz;c){if(coriginal){continue;}arr[i]c;adjacentWords.add(newString(arr));}arr[i]original;}returnadjacentWords;}publicvoidbacktrack(Stringword){temp.add(word);if(word.equals(beginWord)){ListStringladdernewArrayListString(temp);Collections.reverse(ladder);ladders.add(ladder);}else{SetStringprevWordsprevMap.get(word);for(Stringprev:prevWords){backtrack(prev);}}temp.remove(temp.size()-1);}}复杂度分析时间复杂度O ( ∣ Σ ∣ × m × n m × L ) O(|\Sigma| \times m \times n m \times L)O(∣Σ∣×m×nm×L)其中Σ \SigmaΣ是字符集m mm是单词的长度n nn是字典的大小L LL是所有最短转换序列的长度之和这道题中Σ \SigmaΣ是全部小写英语字母∣ Σ ∣ 26 |\Sigma| 26∣Σ∣26。广度优先搜索最多需要遍历每个单词一次对于每个单词计算其下一层的单词的时间是O ( ∣ Σ ∣ × m ) O(|\Sigma| \times m)O(∣Σ∣×m)因此时间复杂度是O ( ∣ Σ ∣ × m × n ) O(|\Sigma| \times m \times n)O(∣Σ∣×m×n)。回溯时对于最短转换序列中的每个单词的操作时间是O ( m ) O(m)O(m)因此时间复杂度是O ( m × L ) O(m \times L)O(m×L)。总时间复杂度是O ( ∣ Σ ∣ × m × n m × L ) O(|\Sigma| \times m \times n m \times L)O(∣Σ∣×m×nm×L)。空间复杂度O ( m × n ) O(m \times n)O(m×n)其中m mm是单词的长度n nn是字典的大小。哈希集合、哈希表和队列需要O ( m × n ) O(m \times n)O(m×n)的空间。注意返回值不计入空间复杂度。

相关新闻

告别失真与延迟!2024年唯一支持实时GPU加速的AI音频引擎曝光(内测资格仅剩83席)

告别失真与延迟!2024年唯一支持实时GPU加速的AI音频引擎曝光(内测资格仅剩83席)

更多请点击: https://intelliparadigm.com 第一章:AI音频处理工具推荐 近年来,AI驱动的音频处理工具在语音增强、音乐分离、语音转文字、音效生成等场景中展现出强大能力。以下工具均经过实际测试,兼顾开源友好性、API稳定性与本…

2026/10/14 3:41:56 阅读更多 →
每天省下2.4小时的AI办公组合拳:微软Power Automate×钉钉智能体×本地化知识库(限免调试包仅开放72小时)

每天省下2.4小时的AI办公组合拳:微软Power Automate×钉钉智能体×本地化知识库(限免调试包仅开放72小时)

更多请点击: https://intelliparadigm.com 第一章:AI办公自动化的核心价值与落地瓶颈 AI办公自动化正从概念验证快速迈向规模化应用,其核心价值在于重构人机协作范式——将重复性高、规则明确、跨系统协同频繁的办公任务交由AI代理持续执行&…

2026/10/10 6:33:04 阅读更多 →
随身wifi刷openwrt变软路由--103s没网的解决

随身wifi刷openwrt变软路由--103s没网的解决

1. 刷入openwrt系统前,在备份文件里面找到下面四个文件,解压出来,将后缀改为.bin,放入openwrt系统包.2. 将备份文件image目录下文件夹解压出来,传入棒子,重启,即可.

2026/10/10 5:41:20 阅读更多 →

最新新闻

带同时取送货的车辆路径问题(VRPSDP)建模与模拟退火求解MATLAB实现

带同时取送货的车辆路径问题(VRPSDP)建模与模拟退火求解MATLAB实现

做物流配送优化的人,十有八九遇到过这种场景:同一个客户点,既要给你送一箱新货,又要让你从他那儿拉走一箱退货或者回收品。如果你把这个问题当成普通的车辆路径问题(VRP)去处理,八成会翻车&…

2026/10/14 3:41:38 阅读更多 →
基于ElementUI的省市区三级联动组件封装与实践

基于ElementUI的省市区三级联动组件封装与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 3:41:38 阅读更多 →
C#集成PaddleOCR C++推理引擎实现本地化OCR识别

C#集成PaddleOCR C++推理引擎实现本地化OCR识别

简介:这是一份面向C#开发者与图像识别初学者的OCR实战Demo,聚焦于快速集成PaddleOCR模型实现多场景文字识别,解决传统OCR部署复杂、环境配置繁琐的问题。资源基于.NET平台构建,整合Clipper与Emgu.CV完成图像预处理,依托…

2026/10/14 3:41:38 阅读更多 →
Unity多人FPS联机框架实战:基于PurrNet的服务器权威架构与延迟补偿方案

Unity多人FPS联机框架实战:基于PurrNet的服务器权威架构与延迟补偿方案

1. 项目背景与整体设计思路先说说这个项目的来龙去脉。我一直在研究Unity联机方案的选型,手头需要搭一个轻量级、能快速出原型验证玩法的多人FPS框架。市面上的方案试了一圈——Mirror生态成熟但风格偏老,Photon收费灵活但免费层限制多,Netco…

2026/10/14 3:41:38 阅读更多 →
美赛特等奖论文拆解:数学建模论文的完整骨架与写作避坑指南

美赛特等奖论文拆解:数学建模论文的完整骨架与写作避坑指南

简介:这份资源是2020年美国大学生数学建模竞赛(MCM/ICM)D题特等奖论文,面向备战美赛的参赛学生、数学建模爱好者及指导教师,尤其适合希望学习社会网络分析(SNA)在体育场景中应用的读者。压缩包内…

2026/10/14 3:41:38 阅读更多 →
DNA到蛋白质的完整路径:转录、翻译与中心法则的分子实战

DNA到蛋白质的完整路径:转录、翻译与中心法则的分子实战

DNA怎么变成蛋白质?这个问题的完整答案,比课本上那张中心法则的箭头要丰富得多。我当年第一次给学生讲清楚转录和翻译的全程时,最深的感受是:知识链条其实不长,但每一环都有大量“看似理所当然、实则经不起追问”的细节…

2026/10/14 3:40:38 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →