【Leetcode 23】合并K个排序链表

题目描述

在这里插入图片描述

解题思路

解法一:暴力法

  • 遍历k个链表,将所有节点值保存到列表中
  • 将列表排序
  • 遍历排序后的列表,创建一个新的有序链表

python代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        self.nodes = []
        tmp = head = ListNode(0)
        for i in lists:
            while i:
                self.nodes.append(i.val)
                i = i.next
        for j in sorted(self.nodes):
            head.next = ListNode(j)
            head = head.next
        return tmp.next

运行结果

时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN),其中 N N N是节点的总数目。

  • 遍历所有的值需花费 O ( N ) O(N) O(N)的时间。
  • 一个稳定的排序算法花费 O ( N l o g N ) O(Nlog N) O(NlogN) 的时间。
  • 遍历同时创建新的有序链表花费 O ( N ) O(N) O(N)的时间。

空间复杂度 O ( N ) O(N) O(N)

  • 排序花费 O ( N ) O(N) O(N)空间(这取决于你选择的算法)。
  • 创建一个新的链表花费 O ( N ) O(N) O(N) 的空间。
    在这里插入图片描述

解法二:分治算法

分治其实就是不断缩小其规模,再不断合并扩大的过程
在这里插入图片描述
找到中间点,将其一分为二,再不停的进行拆分,直至到不能再拆分(规模为1的时候)便返回。
之后开始合并,合并的代码借用了合并两个排序链表的代码。
当两个规模最小的链表合并完后,其规模就变大了,然后不断重复这个合并过程,直到最终得到一个有序的链表。

python代码

 amount = len(lists)
        interval = 1
        while interval < amount:
            for i in range(0, amount - interval, interval * 2):
                lists[i] = self.merge2Lists(lists[i], lists[i + interval])
            interval *= 2
        return lists[0] if amount > 0 else lists

    def merge2Lists(self, l1, l2):
        head = point = ListNode(0)
        while l1 and l2:
            if l1.val <= l2.val:
                point.next = l1
                l1 = l1.next
            else:
                point.next = l2
                l2 = l1
                l1 = point.next.next
            point = point.next
        if not l1:
            point.next=l2
        else:
            point.next=l1
        return head.next 

运行结果

时间复杂度 O ( N log ⁡ k ) O(N\log k) O(Nlogk) ,其中k是链表的数目。

  • 我们可以在 O ( n ) O(n) O(n)的时间内合并两个有序链表,其中 n是两个链表中的总节点数。
  • 将所有的合并进程加起来,我们可以得到:在这里插入图片描述

空间复杂度:O(1).
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值