【力扣算法04】之合并 K 个升序链表- python

news2024/10/6 0:27:17

文章目录

  • 问题描述
    • 示例1
    • 示例2
    • 示例3
    • 提示
    • 思路分析
  • 代码分析
  • 完整代码
    • 额外讲解
  • 完结

问题描述

在这里插入图片描述

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

在这里插入图片描述

示例1

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
 

示例2


输入:lists = []
输出:[]

示例3

输入:lists = [[]]
输出:[]

提示

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i] 按 升序 排列
  • lists[i].length 的总和不超过 10^4

思路分析

在这里插入图片描述

  1. 首先,定义一个辅助方法 mergeTwoLists,用于将两个有序链表合并成一个有序链表。

  2. 接着,定义一个辅助方法 mergeKListsHelper,该方法接收一个链表数组 lists、起始索引 start 和结束索引 end,返回合并后的链表。

  3. mergeKListsHelper 方法中,首先判断起始索引 start 是否大于结束索引 end,如果是,则直接返回 None

  4. 然后,判断起始索引 start 是否等于结束索引 end,如果是,则说明只有一个链表需要合并,直接返回该链表即可。

  5. 如果起始索引 start 小于结束索引 end,则计算中间索引 mid,将链表数组拆分成两个部分。

  6. 调用递归方法 mergeKListsHelper,分别传入起始索引 start 和中间索引 mid,得到合并后的左半部分链表。

  7. 同样地,调用递归方法 mergeKListsHelper,分别传入中间索引 mid+1 和结束索引 end,得到合并后的右半部分链表。

  8. 最后,调用辅助方法 mergeTwoLists,将左半部分链表和右半部分链表合并成一个有序链表,并返回合并后的结果。

  9. 最后,在主方法 mergeKLists 中,判断链表数组 lists 是否为空,如果为空,则直接返回 None

  10. 否则,调用辅助方法 mergeKListsHelper,传入链表数组 lists、起始索引0 和结束索引 len(lists)-1,得到最终合并后的链表。

代码分析

在这里插入图片描述

第1块:

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """

定义了一个名为 Solution 的类,该类包含一个方法 mergeKLists,接收一个参数 lists,并且没有指定返回类型。

第2块:

if not lists:
    return None

判断链表数组 lists 是否为空,如果为空,则直接返回 None

第3块:

n = len(lists)

获取链表数组 lists 的长度,并将其赋值给变量 n

第4块:

while n > 1:
    k = (n + 1) // 2
    for i in range(n // 2):
        lists[i] = self.mergeTwoLists(lists[i], lists[i+k])
    n = k

使用循环进行链表的合并操作。首先判断 n 是否大于1,即还有多个链表需要合并。然后计算中间位置的索引并赋值给变量 k。接着使用循环遍历链表数组的前一半元素的索引,调用辅助方法 mergeTwoLists 对当前元素和对应的后半部分元素进行合并,并将结果赋值给当前元素。最后将数组长度更新为中间位置,并继续下一轮循环。

第5块:

return lists[0]

返回合并后的链表数组的第一个元素,即最终合并后的链表。

第6块:

def mergeTwoLists(self, l1, l2):
    if not l1:
        return l2
    if not l2:
        return l1
    if l1.val < l2.val:
        l1.next = self.mergeTwoLists(l1.next, l2)
        return l1
    else:
        l2.next = self.mergeTwoLists(l1, l2.next)
        return l2

定义了一个辅助函数 mergeTwoLists,接收两个参数 l1l2。该函数用于合并两个有序链表。首先判断链表 l1 是否为空,如果为空,则直接返回链表 l2。然后判断链表 l2 是否为空,如果为空,则直接返回链表 l1。接着判断链表 l1 的头结点的值是否小于链表 l2 的头结点的值。如果成立,将链表 l1 的下一个节点和链表 l2 传入递归调用的 mergeTwoLists 方法,并将返回的结果赋值给链表 l1 的下一个节点,并返回链表 l1。如果不成立,则将链表 l1 和链表 l2 的下一个节点传入递归调用的 mergeTwoLists 方法,并将返回的结果赋值给链表 l2 的下一个节点,并返回链表 l2

完整代码

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        if not lists:  # 如果链表列表为空
            return None  # 返回 None
        n = len(lists)  # 获取链表列表的长度,并赋值给变量 n
        
        while n > 1:  # 当链表列表的长度大于 1 时,进行循环操作
            k = (n + 1) // 2  # 计算中间位置 k
            for i in range(n // 2):  # 对于每个索引 i,进行以下操作
                lists[i] = self.mergeTwoLists(lists[i], lists[i+k])  # 将 lists[i] 和 lists[i+k] 进行合并,并赋值给 lists[i]
            n = k  # 将 n 更新为 k,继续下一轮循环
        
        return lists[0]  # 返回合并后的链表列表的第一个元素,即最终合并后的链表

    def mergeTwoLists(self, l1, l2):
        if not l1:  # 如果 l1 为空
            return l2  # 直接返回 l2
        if not l2:  # 如果 l2 为空
            return l1  # 直接返回 l1
        
        if l1.val < l2.val:  # 如果 l1 的头结点的值小于 l2 的头结点的值
            l1.next = self.mergeTwoLists(l1.next, l2)  # 将 l1 的下一个节点与递归调用的 self.mergeTwoLists(l1.next, l2) 结果进行合并,并赋值给 l1.next
            return l1  # 返回 l1
        else:  # 否则
            l2.next = self.mergeTwoLists(l1, l2.next)  # 将 l1 和 l2 的下一个节点与递归调用的 self.mergeTwoLists(l1, l2.next) 结果进行合并,并赋值给 l2.next
            return l2  # 返回 l2

额外讲解

  1. class Solution(object)::定义了一个名为 Solution 的类。

  2. def mergeKLists(self, lists)::定义了一个方法 mergeKLists,接收一个参数 lists

  3. if not lists::判断链表数组 lists 是否为空。如果为空,则直接返回 None

  4. n = len(lists):获取链表数组的长度。

  5. while n > 1::进入循环,条件是链表数组的长度大于1,即还有多个链表需要合并。

  6. k = (n + 1) // 2:计算中间位置的索引。

  7. for i in range(n // 2)::遍历链表数组的前一半元素的索引。

  8. lists[i] = self.mergeTwoLists(lists[i], lists[i+k]):调用辅助方法 mergeTwoLists,将当前元素和对应的后半部分元素进行合并,并将结果赋值给当前元素。

  9. n = k:更新链表数组的长度为中间位置。

  10. return lists[0]:返回合并后的链表数组的第一个元素,也就是最终合并后的链表。

  11. def mergeTwoLists(self, l1, l2)::定义了一个辅助函数 mergeTwoLists,接收两个参数 l1l2

  12. if not l1::判断链表 l1 是否为空。如果为空,则直接返回 l2

  13. if not l2::判断链表 l2 是否为空。如果为空,则直接返回 l1

  14. if l1.val < l2.val::判断链表 l1 的头结点的值是否小于链表 l2 的头结点的值。

  15. l1.next = self.mergeTwoLists(l1.next, l2):递归调用 mergeTwoLists 方法,将 l1 的下一个节点和 l2 传入,并将返回的结果赋值给 l1 的下一个节点。

  16. return l1:返回合并后的链表 l1

  17. else::如果链表 l1 的头结点的值大于等于链表 l2 的头结点的值。

  18. l2.next = self.mergeTwoLists(l1, l2.next):递归调用 mergeTwoLists 方法,将 l1l2 的下一个节点传入,并将返回的结果赋值给 l2 的下一个节点。

  19. return l2:返回合并后的链表 l2

完结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简要介绍 | 融合深度学习与符号逻辑:神经符号结合的探索

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对神经符号结合进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 融合深度学习与符号逻辑&#xff1a;神经符号结合的探索 Neuro-Symbolic AI 本文将探讨神经符号结合的概念、原理、研究现状、挑战…

推荐分布式系统案例课

你将获得 一线大厂分布式系统设计方法论&#xff1b; 分布式核心技术详解&#xff1b; 系统架构师面试技巧&#xff1b; 百万年薪架构师成长路径。 演示地址&#xff1a;www.runruncode.com/houduankaifa/19452.html 课程介绍 是否具备分布式系统的架构和设计能力&#xff0c;是…

typescript helloword

创建文件夹 创建ch01文件夹 新建tsconfig.json {"compilerOptions": {"strict": true,"target": "ES5"} }“tsconfig.json”是TypeScript编译器默认使⽤的配置⽂件。此例中的配置⽂件启⽤了所有的严格类型检查编译选项&#xff0c;…

经过半年的努力,终于成为了谷歌开发者专家(GDE)

大家好&#xff0c;我是拭心。 几天前&#xff0c;我终于收到了一封心心念念的邮件&#xff1a; 邮件的意思是&#xff1a;我正式成为了一名 GDE&#xff01; 这封邮件来之不易&#xff0c;背后是半年多的准备、三次公开分享和两轮英文面试&#xff0c;我想有必要做一个总结&…

VMware vSphere 7 Update 3n 下载

VMware vSphere 7 Update 3n 下载 vCenter Server & ESXi, DellEMC, HPE, Cisco, LENOVO, FUJITSU, NEC, Inspur, Hitachi Custom Image 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-7-u3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留…

存储函数和存储过程的简单应用

创建存储函数 使用select调用 创建存储过程avg_sai 去调用他

stm32 ->HAL库重定向printf,实现串口打印

步骤 在CubeMX中初始化uart引脚 MX_USART1_UART_Init();包含printf函数的头文件stdio.h 重定义printf函数 int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); return ch; }勾选Use MicroLIB 编译烧录 实现代码 /* Private i…

redis实现相关分布式锁

为什么需要分布式锁 我们知道&#xff0c;当多个线程并发操作某个对象时&#xff0c;可以通过synchronized来保证同一时刻只能有一个线程获取到对象锁进而处理synchronized关键字修饰的代码块或方法。既然已经有了synchronized锁&#xff0c;为什么这里又要引入分布式锁呢&…

vue打包、网站运行速度优化

最近在做公司的官网&#xff0c;遇到的首要问题就是初次进入网站时&#xff0c;加载很慢&#xff0c;首页的视频和字体甚至需要30秒才能完全展示出来&#xff0c;用户体验可以说时很差了。接下来说几个优化的点。 一、减小图片的体积 如果项目中的图片过于多&#xff0c;并且体…

Set up the compilation environment for ESP8266-RTOS-SDK using Git on Windows

Software to be installed&#xff1a; Git BashPython Environment&#xff0c;ESP8266 Master require Python v3 environment. Please check “add to PATH” while installing Open Git Bash&#xff0c;Enter a local disk&#xff0c;create an empty folder, enter the …

【雕爷学编程】Arduino动手做(159)---RCWL-0515微波检测模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

十大经典排序算法(代码实现),建议收藏

兜兜转转&#xff0c;一晃年关将至。时间证明了一个道理&#xff0c;学啥忘啥&#xff0c;学的越快忘得越快&#xff0c;还不如踏踏实实写点笔记心得来的实在。 编程初学期间&#xff0c;排序算法是让人抓头最多的一块。为什么我连最简单的冒泡排序都理解不了&#xff0c;我是…

webpack基础知识

webpack基础知识 1、定义2、环境安装3、初始化项目4、简单使用 1、定义 webpack的本质是一个第三方模块包&#xff0c;用于分析&#xff0c;并打包代码 支持所有类型的文件打包支持less/sass> css支持ES6/7/8>ES5压缩代码&#xff0c;提高加载速度 2、环境安装 yarn安…

Java并发编程中的HashMap、HashTable、ConcurrentHashMap

1、HashMap 1.1、为什么HashMap非线程安全的 &#xff08;1&#xff09;竞态条件 当多个线程同时对 HashMap 进行写操作&#xff08;如插入、删除、修改&#xff09;&#xff0c;由于没有同步控制&#xff0c;可能会导致数据不一致的情况。例如&#xff0c;两个线程同时向同…

LLM 生成视频 - pika

文章目录 关于 pika申请试用2023-07-12 关于 pika A powerful Text-to-Video platform that can unleash your creativity simply by typing. 官网: https://www.pika.art/官方 twitter : https://twitter.com/pika_labs相关功能介绍 相关报道/博客: 图片生成视频 from : h…

如何给视频配音?这几种配音方法一看就会

怎么给视频进行配音呢&#xff1f;如果原始视频的录音质量较差&#xff0c;存在噪音、回音或杂音等问题&#xff0c;配音可以用来替换原始音频&#xff0c;以提高声音质量和清晰度&#xff0c;或者是我们想要给视频配上一段搞笑的方言配音&#xff0c;怎么怎么做呢&#xff1f;…

超级自动化的3年:财务、IT等通用场景占比高达65%,垂直领域玩家开始晋级

从信息化时代走向数字化时代&#xff0c;企业的最终目标即利用先进的数字技术完成数字化转型升级&#xff0c;而这绝不是将业务、流程、数据、表单等搬到线上就“完事⼉”。 在此背景下&#xff0c;Gartner于2019年提出“超级自动化”&#xff0c;之后全球范围内越来越多的企业…

【C++】-关于vector的两个习题(二维数组和多路递归)

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你…

论文浅尝 | 少样本学习的语言模型的持续训练

笔记整理&#xff1a;王贵涛&#xff0c;东南大学硕士&#xff0c;研究方向为自然语言处理 链接&#xff1a;https://github.com/UIC-Liu-Lab/CPT 一、动机 克服灾难性遗忘&#xff08;CF&#xff09;是持续学习&#xff08;CL&#xff09;的一个主要目标。目前有许多方法&…

施密特(Gram-Schmidt)正交化

引自于点击打开 如果没有空间向量解析几何基础&#xff0c;理解起来有些困难&#xff0c;因此稍微解说一下。 两个向量的正交变换我们分为3步&#xff1a; &#xff08;a1,a1)/ (|a1| * |a2|)是a1,a2之间的夹角的cos值cos值乘以|a2|后&#xff0c;得到a2在a1上映射的长度值&…