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

LeetCode 126题:单词接龙 II

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣!

  • 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注
    在这里插入图片描述

  • 导航

    • LeetCode解锁1000题: 打怪升级之旅:每题都包括3-5种算法,以及详细的代码实现,刷题面试跳槽必备
    • 漫画版算法详解:通过漫画的形式和动态GIF图片把复杂的算法每一步进行详细可视解读,看一遍就掌握
    • python源码解读:解读python的源代码与调用关系,快速提升代码质量
    • python数据分析可视化:企业实战案例:企业级数据分析案例与可视化,提升数据分析思维和可视化能力
    • 程序员必备的数学知识与应用:全面详细的介绍了工程师都必备的数学知识

期待与您一起探索技术、持续学习、一步步打怪升级 欢迎订阅本专栏❤️❤️

题目描述

给定两个单词(beginWordendWord)和一个字典 wordList,找出所有从 beginWordendWord 的最短转换序列的转换过程,转换需遵循如下规则:

  1. 每次转换只能改变一个字母。
  2. 转换过程中的中间单词必须在字典 wordList 中。

说明:

  • 如果不存在这样的转换序列,返回一个空列表。
  • 所有单词具有相同的长度。
  • 所有单词只包含小写字母。
  • 字典 wordList 是非空的,且不包含重复的单词。
  • beginWordendWord 是非空的,且不相同。

示例:

输入:

beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出:

[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]
]

方法一:广度优先搜索(BFS)+ 回溯

解题步骤

  1. 使用 BFS 确定最短路径长度并记录每个单词的所有可能前驱词。
  2. endWord 开始,使用回溯法根据前驱词列表构造所有有效路径。

Python 示例

from collections import defaultdict, dequedef findLadders(beginWord, endWord, wordList):if endWord not in wordList:return []wordList = set(wordList)layer = {}layer[beginWord] = [[beginWord]]while layer:newlayer = defaultdict(list)for word in layer:if word == endWord:return layer[word]for i in range(len(word)):for c in 'abcdefghijklmnopqrstuvwxyz':newword = word[:i] + c + word[i+1:]if newword in wordList:newlayer[newword] += [j + [newword] for j in layer[word]]wordList -= set(newlayer.keys())layer = newlayerreturn []# Example usage
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
print(findLadders(beginWord, endWord, wordList))

算法分析

  • 时间复杂度: O(N * M^2),N 是 wordList 的长度,M 是单词的长度。
  • 空间复杂度: O(N * M),存储转换路径所需空间。

方法一:广度优先搜索(BFS)+ 回溯 图解说明

在方法一中,我们使用广度优先搜索(BFS)和回溯的组合来解决单词接龙 II 问题。这种方法的核心在于逐层扩展当前单词,直到找到目标单词 endWord。图解的详细步骤如下:

  1. 初始化

    • 创建一个字典 layer 来存储每一层的单词及其对应的路径。初始时,layer 包含 beginWord 和它自身构成的路径(["hit"])。
  2. 广度优先搜索

    • 遍历当前层的每个单词,尝试改变单词中的每一个字符,用 26 个字母替换,生成新的单词。
    • 检查每个新生成的单词是否在 wordList 中。如果在,将其加入到下一层的搜索中,并记录路径。
    • 重要的是,一旦一个单词被用于构建路径,它就会从 wordList 中移除,这避免了重复访问并减少了搜索空间。
  3. 路径记录

    • 对于每个有效的转换单词,我们更新 newlayer 字典,将新单词的路径扩展为从上一层单词衍生出的所有可能路径。
    • 例如,从 “hit” 到 “hot”,如果 “hot” 能转换为 “dot” 和 “lot”,则路径更新为从 “hit” 到 “hot” 再到这些单词的路径。
  4. 检查终点

    • 在每层搜索结束时,检查 endWord 是否已经出现在当前层的路径中。如果出现,就意味着找到了最短路径,函数返回当前层对应的 endWord 的所有路径。
  5. 循环继续

    • 更新 layernewlayer,进行下一轮层的搜索,直到找到 endWord 或者没有新单词可以搜索。
示意图

考虑 beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] 的情况:

Layer 0: hit|
Layer 1: hot/ \
Layer 2:dot lot/    \
Layer 3:dog  log\     /
Layer 4:  cog

在这个示意图中,广度优先搜索首先找到与 “hit” 一个字母不同的所有单词(即 “hot”),然后再从 “hot” 扩展到 “dot” 和 “lot”,以此类推,直到到达 “cog”。每一步都保证是最短的可能路径,因为我们是逐层扩展的。

方法二:双向广度优先搜索(Bi-directional BFS)

解题步骤

  1. beginWordendWord 同时开始搜索,每次扩展较小的层。
  2. 当两个搜索方向在中间某处相遇时,使用所有累积的路径构建最终路径。

Python 示例

def findLadders(beginWord, endWord, wordList):if endWord not in wordList:return []tree, words, n = defaultdict(set), set(wordList), len(beginWord)if beginWord in words: words.remove(beginWord)found, q, nq = False, {beginWord}, set()while q and not found:words -= set(q)for x in q:for y in [x[:i] + c + x[i + 1:] for i in range(n) for c in 'abcdefghijklmnopqrstuvwxyz']:if y in words:if y == endWord: found = Trueelse: nq.add(y)tree[x].add(y)q, nq = nq, set()def bt(x): return [[x]] if x == endWord else [[x] + rest for y in tree[x] for rest in bt(y)]return bt(beginWord)# Example usage
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
print(findLadders(beginWord, endWord, wordList))

算法分析

  • 时间复杂度: O(N * M^2),类似于单向 BFS。
  • 空间复杂度: O(N * M),需要存储中间状态和构建路径。

算法图解与说明

双向广度优先搜索可以更快地找到路径因为它从两端同时搜索,减少了搜索的广度。

这两种方法都可以有效地找出所有最短的从 beginWordendWord 的路径,第二种方法通常更快,尤其是在大数据集上。

🌹🌹如果觉得这篇文对你有帮助的话,记得一键三连关注、赞👍🏻、收藏是对作者最大的鼓励,非常感谢 ❥(^_-)

❤️❤️作者知识有限,如有错误,请各位大佬评论区批评指正,不胜感激❥(^_-)
在这里插入图片描述

相关文章:

LeetCode 126题:单词接龙 II

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…...

5.14(Vue2)

1.单页应用程序是指所有功能都在一个html页面上 单页面应用程序,之所以开发效率高,性能好,应用体验好,最大的原因就是:页面按需更新。 2.Vue中的路由 路径和组件的映射关系 Vue中的路由插件:VueRouter&…...

使用openssl生成自签名证书

使用openssl生成自签名证书 1. 交互式生成2. 一步生成参考 1. 交互式生成 自签名 SSL 证书的生成涉及一个简单的 3 步过程: 步骤 1:创建服务器私钥 openssl genrsa -out cert.key 2048步骤 2:创建证书签名请求 (CSR) openssl req -new -k…...

【java】泛型

文章目录 1. 什么是泛型?1.1 背景1.2 泛型的概念1.3 泛型的好处 2. 泛型类、接口...2.1 泛型类2.2 从泛型类派生子类2.2.1 子类也是泛型类,子类和父类的泛型类型要一致2.2.2 子类不是泛型类,父类要明确泛型的数据类型 2.3 泛型接口2.4 泛型方…...

计算思维的理解

2006年,卡内基梅隆大学周以真教授首次系统性地定义了计算思维。这一年,她在美国计算机权威期刊《Communications of the ACM》上发表了题为《Computational Thinking》的论文,由此开启了计算思维大众化的全新历程。 周以真(Jeanne…...

Python中tkinter编程入门4

在Python中tkinter编程入门3-CSDN博客中创建了Button控件,点击该控件就会产生一个点击事件,在创建Button控件时指定该点击事件的处理程序后,按键控件就会对用户的点击事件产生响应。 1 定义事件处理器 定义事件处理器就是一个自定义的函数。…...

Milvus的系统架构

简介 Milvus的构建在许多知名的向量搜索库比如Faiss, HNSW, DiskANN, SCANN等之上的,它针对稠密向量数据集的相似搜索而设计,能支持百万、十亿甚至万亿级别的向量搜索。 Milvus支持数据分片,流式数据插入,动态schema&#xff0c…...

MFC中关于CMutex类的学习

MFC中关于CMutex类的学习 最近在项目中要实现两个线程之间的同步,MFC中提供了4个类,分别是CMutex(互斥量)、CCriticalSection(临界区)、CEvent(事件对象)、CSemaphore(信号量)。有关这4个类的说明,大家可以参考微软官方文档: CM…...

删除表空间

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 当某个表空间中的数据不再需要时,或者新创建的表空间不符合要求时,可以考虑删除这个表空间。若要删除表空间,则需要用户具有 DROP TABLESP…...

下载element-ui报错

此错误表示尝试从npm注册表下载“resize observer polyfill”包时超时。这可能是由于网络连接问题或npm注册表服务器的问题。 要解决此问题,您可以尝试以下步骤: 1.重试npm install命令:有时,网络问题会导致临时超时。再次运行npm…...

[原创](Modern C++)现代C++的std::bind花式绑定,使用方式大全.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…...

Unity射击游戏开发教程:(13)如何在Unity中播放音效

在本文中,我将向大家展示一些为游戏添加声音的不同方法。 我们为游戏添加声音的第一种方法是播放背景音乐。在此,我们将创建游戏对象(“音频管理器”)并创建一个子游戏对象(“背景音乐”)。该子游戏对象将是播放音乐的对象,因此需要向其添加音频源组件。如果没有音频源组…...

Swift—手写防抖、手写图片预加载与多张图片拼接

什么是防抖,为什么要防抖? 比如我们在文档在线编辑中修改文档内容,总不能打一个字就发送一次更新请求吧,用户疯狂点击一个按钮,总不能一直触发按钮的逻辑吧。防抖被用于避免频繁触发的事件。 Swift实现防抖代码&…...

Redis过期键删除策略

Redis有三种过期键的删除策略。 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除策略。惰性删除:放任键过期不管,但每次从键空间获取键时&#xff0c…...

413 Request Entity Too Large

问题 平台上传文件接口报:413 Request Entity Too Large。 原因 从字面意思就能看出来,是上传文件过大导致的。 一般解决 一般情况下修改nginx配置文件中client_max_body_size参数的大小就行了。可以在http{ }中设置。也可以在server{ }中设置。还可…...

工业无风扇计算机的优点

无风扇计算机往往采用紧凑且密封的外形,使其坚固耐用,使其能够在需要现场工程师进行维护之前承受恶劣的环境数年。机载移动部件较少或没有移动部件会降低组件无法按预期运行的可能性,或者更糟糕的是发生故障和损坏。采用工业组件和较低的散热…...

个人学习计划

vue前端(一周) 05/14 - 05/19 Html、css复习、vue基础复习、axios复习 05/14 ElementUI学习 05/15 JWT集成验证码、token 05/16 vue-route多角色登录 05/17 增删查改、文件下载 05/18 Echart饼状图 05/19 📌 附加学习: 父子传值三…...

【电控实物-LK电机】

参数 Kt 0.11 N.M/A...

《Mybatis》系列文章目录

什么是 MyBatis? MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff…...

ARM机密计算组件

安全之安全(security)博客目录导读 目录 ​一、硬件架构 1、RME 二、软件和固件架构 1、RMM 2、其他固件标准(例如PSCI) 三、开源实现 1、TF-A 2、Veraison 3、工具链 四、动态TrustZone技术 Arm机密计算架构(Arm CCA)引入了一系列硬件和软件…...

XML Group端口详解

在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...