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

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

问题描述


给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。


示例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


完结


相关文章
|
10天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
41 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
10天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
36 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
10天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
50 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
15天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
15天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
32 2
|
24天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
26 3
|
24天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
24天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
27天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
72 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
下一篇
无影云桌面