合并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))       
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值