leetcode(14)-合并k个排序链表

yedaoxiaodi 2020-01-04

合并?k?个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

#输入:
[
? 1->4->5,
? 1->3->4,
? 2->6
]
#输出:
1->1->2->3->4->4->5->6

链接:https://leetcode-cn.com/problems/merge-k-sorted-lists

自己的思路

在k个链表中找到一个比较节点,然后把k个链表分成两部分,一部分都比比较节点小,一部分都比比较节点大,然后递归。

但是时间太慢了,原因一个是,找到的比较节点越靠近中位数越好,但是不好操作,第二个就是分成两部分的时候要查找,只能顺序查找。(变成数组也许会好一点,二分)

import random
class Solution:
    def mergeKLists(self, lists)-> ListNode:
        lists = [list for list in lists if list is not None]
        if len(lists)==0:
            return None
        num = len(lists)
        i = random.randint(0,num-1)
        com_node = lists[i]
        com_val = lists[i].val
        lists[i] = lists[i].next
        lists_1 = []
        for j in range(num):
            if i!=j:
                head = lists[j]
                tail = None
                while lists[j].val<=com_val:
                    tail = lists[j]
                    lists[j] = lists[j].next
                    if lists[j] is None:
                        break
                if tail is not None:
                    tail.next = None
                    lists_1.append(head)
        list_1 = self.mergeKLists(lists_1)
        list_2 = self.mergeKLists(lists)
        if list_1 is not None: 
            head  = list_1
            while True:
                if list_1.next is not None:
                    list_1 = list_1.next
                else:
                    list_1.next = com_node
                    break
        else:
            head = com_node
        com_node.next = list_2
        return head

官方思路1-分治法

每次合并两个链表,合并一次之后剩余k/2,再合并一次剩余k/4。时间复杂度(NlogK)

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

官方题解2-用优先队列优化

from queue import PriorityQueue
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
    def __lt__(self, other):
        return self.val<other.val

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

相关推荐