刷题——合并K个排序链表

先看题目

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

示例:

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


拿到题按照规矩,首先先暴力一遍,把拿到的数据全部放进数组sort一下,然后放进一个链表

ps:太久没有接触链表了,几乎忘完了...写next的时候还在用->next =-=

# 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 = []
        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

时间用了224ms

接下来看看有没有什么省时间的算法

首先,先试着分析只有两个的链表的时候

我去LeetCode上面搜了一下,还真有这一题

https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode/

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4


既然是已经排序好的,那就先比较这两个链表的首个数字,比较出小的next,之后再次进行比较,选小的next一直循环下去

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

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(0)
        point = head
        while l1 and l2:
            if l1.val <= l2.val:
                point.next = l1
                l1 = l1.next
            else:
                point.next = l2
                l2 = l2.next
            point = point.next
        if l1:
            point.next = l1
        else:
            point.next = l2
        return head.next

那么放在K个链表里面,也可以采取这种方式,这里用到了队列这样更加方面

参考资料:百度优先队列。

from Queue import PriorityQueue
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        q = PriorityQueue()
        head = point = ListNode(0)
        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

花费的时间192ms,比暴力的时间稍微快一点

想不出什么办法,只能去参考题解了,连接在下面。
链接:https://leetcode-cn.com/problems/two-sum/solution/he-bing-kge-pai-xu-lian-biao-by-leetcode/

这个算法是两两合并的算法进行了优化。

不得不说,我做了那到合并两个链表的题目二也没有想过通过一轮一轮的方法来做这道题,而是直接把合并两个链表的方法(不听取最小的放在最后的链表里面)直接用了=-=

只能说太死脑筋啦,今天学习到了,代码也贴在下面:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
from Queue import PriorityQueue
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        len_of_lists = len(lists)
        if len_of_lists == 0:
            return 
        len_of_next = 1
        while len_of_next < len_of_lists:
            for i in range(0, len_of_lists - len_of_next, len_of_next*2):
                lists[i] = self.merge2Lists(lists[i], lists[i+len_of_next])
            len_of_next *= 2
        return lists[0]
    def merge2Lists(self, l1, l2):
        head = point = ListNode(0)
        while l1 and l2:
            if l1.val <= l2.val:
                point.next = ListNode(l1.val)
                l1 = l1.next
            else:
                point.next = ListNode(l2.val)
                l2 = l2.next
            point = point.next
        if l1:
            point.next = l1
        else:
            point.next = l2
        return head.next

这道题用了三种方法,还进行了优化,感觉学到了很多,以后想问题的时候格局要大一点咯

原文地址:https://www.cnblogs.com/fanwenkeer/p/11270796.html