力扣Leetcode:23. 合并K个升序链表(Python,分治)

这篇博客探讨了如何高效地合并多个已排序的链表,将其转化为一个有序链表。博主介绍了从简单的双链表合并到使用归并排序策略解决多个链表合并的问题,详细阐述了分治算法的思想和递归实现。代码示例展示了Python中的解决方案,包括合并两个链表的函数和基于归并的分治算法。
摘要由CSDN通过智能技术生成

题目描述

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

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

示例

输入: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

题解

这是一道困难题目。这道题目困难的地方在于,不确定链表数组中有多少个有序链表,因此无法简单地用若干指针实现。例如,对于两个有序链表的合并,直接使用双指针即可,通过修改原链表next指针的方法实现原地合并。

对于多个有序链表的合并问题,直接地,我们可以想到逐一合并的方式——首先第一个链表与第二个链表合并,得到一个新的有序链表,再与第三个链表合并。第一次合并复杂度为O(2n),第二次为O(4n),以此类推,通过等比数列求和得到最终的时间复杂度O(K2n)。

更进一步地,想到“分而治之”的思想,即归并。对于k个链表,我们首先将它们等分为两组,之后每一组再分为两组,以此类推,直至某一组内只有零个、一个或两个有序链表。

  • 若一组内没有链表:直接返回一个None;
  • 若一组只有一个有序链表:直接返回该链表;
  • 若一组内有两个有序链表:直接使用合并两个链表的方法,返回这两个链表的合并结果。

因此,这里的分治算法分为分、合这两个部分,每次分都是在对半分每次合并都是在合并两个有序链表。具体实现上,自上向下地采用递归的方法。

Python代码

class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class Solution(object):
    def merge_two(self, list1, list2):
        if not list1:
            return list2
        if not list2:
            return list1
        head, x, y = ListNode(), list1, list2
        curr = head
        while x and y:
            if x.val < y.val:
                curr.next = x
                x = x.next
            else:
                curr.next = y
                y = y.next
            curr = curr.next
        curr.next = x if x else y
        return head.next

    def merge(self, lists, l, r):
        if r < l:
            return None
        if l == r:
            return lists[l]
        mid = (l + r) / 2
        return self.merge_two(self.merge(lists, l, mid), self.merge(lists, mid + 1, r))

    def mergeKLists(self, lists):
        return self.merge(lists, 0, len(lists) - 1)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔卿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值