leetcode 23. Merge k Sorted Lists 几种解法

1.取值排序法
首先我们最先想到的可能是将所有链表的值放进一个数组中,然后进行排序,最后将排序后的元素依次构建新的链表。代码如下:

 class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        self.nodes = []
        head = point = ListNode(0)
        for l in lists:
            while l:
                self.nodes.append(l.val)
                l = l.next
        for x in sorted(self.nodes):
            point.next = ListNode(x)
            point = point.next
        return head.next

假设N为所有节点的总数量,这种方法的时间复杂度是 O(Nlog N),空间复杂度是O(N)。
2.逐个比较法
这种方法是将每个链表依次从头开始比较,每次取k个链表中最小的,接在新的链表后,如下图所示:
这里写图片描述
这里写图片描述
由于获取每个排好序的节点时每个链表都要和k-1个链表比较一次,因此N个节点的时间复杂度是 O(kN),空间复杂度是O(N)。
3.优先队列法

优先队列可以根据元素值的大小来设置优先级,值最大/最小的拥有最高的优先级。这样,我们就可以快速地获取队列中最大/最小的元素。优先队列有两个核心方法:插入元素,删除最大元素,在python的PriorityQueue中可以分别使用put()和get()方法实现:

from Queue import PriorityQueue

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        head = point = ListNode(0)
        q = PriorityQueue()
        for l in lists:
            if l:
                q.put((l.val, l))
        while not q.empty():
            val, node = q.get()
            point.next = ListNode(val)
            point = point.next
            node = node.next
            if node:
                q.put((node.val, node))
        return head.next

对于N个节点每次比较进行O(logk) 的插入删除操作,因此总的时间复杂度是 O(Nlog k),空间复杂度是O(N)。
4.两两合并法
将k个链表的合并转化为两个链表合并问题。两个链表合并的方法如下:

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        l0 = ListNode(None)
        l = l0
        while l1 and l2:
            if l1.val > l2.val:
                l1, l2 = l2, l1
            l.next = l1
            l = l.next
            l1 = l1.next
        l1 = l1 or l2
        l.next = l1
        return l0.next

这种方法的时间复杂度是O(kN),空间复杂度是O(1).
5.分治法
如下图所示:
这里写图片描述

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        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

可以看出,这种方法对于每一个节点需要重复log(k)次,因此共需要Nlog(k)时间复杂度,空间复杂度只需要常数级。

猜你喜欢

转载自blog.csdn.net/iqqiqqiqqiqq/article/details/80188495
今日推荐