• 合并k个已排序的链表


    合并k个已排序的链表-牛客

    思路

    使用归并排序,用递归实现。
    k个链表,相当于k个子问题,需要划分为链表数量更少的子问题,直到每一组合并时是两两合并,然后继续往上合并,这个过程基于递归:

    • 递归函数终止条件: 直到左右区间相等或左边大于右边。
    • 递归函数入参和返回值:入参:存放k个链表的lists、区间首、尾结点;返回值: 每级返回已经合并好的子问题链表。
    • 本层逻辑: 对半划分,将划分后的子问题合并成新的链表。

    合并:与合并两个排序链表相似,使用双指针,分别指向2个链表的表头,虚拟头结点为为新链表的表头

    步骤:
    1:从链表数组的首和尾开始,每次划分从中间开始划分,划分成两半,得到左边n/2n/2n/2个链表和右边n/2n/2n/2个链表。
    2:继续不断递归划分,直到每部分链表数为1.
    3:将划分好的相邻两部分链表,按照两个有序链表合并的方式合并,合并好的两部分继续往上合并,直到最终合并成一个链表

    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    #
    # 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    #
    # 
    # @param lists ListNode类一维数组 
    # @return ListNode类
    #
    class Solution:
        def mergeKLists(self , lists: List[ListNode]) -> ListNode:
            # 归并排序:双指针+分治
            #K个链表归并排序
            return self.divideMerge(lists, 0, len(lists)-1)
        
        def Merge2(self, phead1, phead2) -> ListNode:
            #合并2个有序链表
            #一个已空,直接返回另一个
            if phead1==None:
                return phead2
            if phead2==None:
                return phead1
            #虚拟表头
            head=ListNode(0)
            cur=head
            #2个链表都不为空
            while phead1 and phead2:
                if phead1.val <= phead2.val:
                    cur.next=phead1
                    #只移动取值的指针
                    phead1=phead1.next
                else:
                    cur.next=phead2
                    phead2=phead2.next
                #虚拟指针后移
                cur=cur.next
            #哪个链表有剩,直接连后面
            if phead1:
                cur.next=phead1
            else:
                cur.next=phead2
            #返回值去掉虚拟头结点
            return head.next
                
        
        def divideMerge(self, lists, left, right) -> ListNode:
            #划分区间
            #递归终止条件
            if left > right:
                return
            elif left==right:
                return lists[left]
            else:
                #从中间分成两部分,再将排序好的两段合并
                mid=(left+right)//2
                return self.Merge2(self.divideMerge(lists, left, mid), self.divideMerge(lists, mid+1, right))       
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
  • 相关阅读:
    基于C语言实现的足球信息查询系统 课程报告+项目源码+演示PPT+项目截图
    【C++】C++中SDKDDKVer.h和WinSDKVer.h函数库详解
    深入理解 MyBatis 的核心配置
    力扣练习——55 搜索二维矩阵 II
    分库分表ShardingSphere-JDBC笔记整理
    《洛谷刷题笔记》day1
    Qt(day1)
    YOLOv5源码中的参数超详细解析(1)— 项目目录结构及文件(包括源码+网络结构图)
    Python环境的安装及配置
    JavaScript:预解析
  • 原文地址:https://blog.csdn.net/Lucky_main/article/details/125513217