LeetCode 算法题库【23】——合并K个排序链表

合并K个排序链表

题目描述:

timu

解题思路:
  • 第一种:这个方法比较暴力,思路也很简单。就是把全部的链表都合成一个链表,然后对这一个链表进行排序,这样就把问题大大简化了。我们用p来存放结合后的链表,通过forwhile循环将lists的元素一个一个放入p中。然后排序,并放入新的链表中返回。
  • 时间复杂度:O(NlogN)
# 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:
        p = []
        _lis = head = ListNode(0)
        for i in lists:
            while i:
                p.append(i.val)
                i = i.next
        for j in sorted(p):
            _lis.next = ListNode(j)
            _lis = _lis.next
        return head.next

1

  • 第二种:下面这个方法的思路挺不错的。用的是优先级队列的解法,其中用到了heapq模块,也就是堆队列的算法。这里用了一个大小为K的最小堆,通过用优先队列和自定义的降序来实现。先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中,这里heapq.heappop(p)是取出堆中最小元素,所以我们依次将最小元素从堆中取出,然后放入新链表,最后返回。
  • 时间复杂度:O(Nlogk)
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
import heapq

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        p = []
        _node = ListNode(0)
        a = _node
        for i in range(len(lists)):
            if lists[i]:
                heapq.heappush(p, (lists[i].val, i))
        while p:
            _, index = heapq.heappop(p)
            head = lists[index]
            a.next = head
            a = a.next
            if head.next:
                heapq.heappush(p, (head.next.val, index))
                lists[index] = head.next
                head.next = None
        return _node.next

或者这样的写法也行,和上面的区别就是入堆的方法用的不一样,这里用到了enumerate函数来入堆。

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        q, curs = [], []  # curs存K个链表滑动的头指针
        for i, n in enumerate(lists):
            if n is not None:
                heapq.heappush(q, (n.val, i))
            curs.append(n)
        _node = ListNode(0)
        a = _node
        while q:
            val, index = heapq.heappop(q)
            a.next = lists[index]
            a = a.next
            lists[index] = lists[index].next
            if lists[index] is not None:
                heapq.heappush(q, (lists[index].val, index))
        return _node.next

2

  • 第三种:分治法。这个方法将利用归并和排序的思想,利用递归方法和分治法将链表数组一直划分,变成越来越小的半链表数组,然后再对半链表数组进行排序,最后再通过递归的步骤将排好序的半链表数组合,合并成为越来越大的有序链表。简单来说就是一直在不停的对半划分,最后再结合在一起。
  • 时间复杂度:O(Nlogk)
# 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:
        if len(lists) == 0:
            return None
        return self.__merge_k_lists(lists, 0, len(lists) - 1)

    def __merge_k_lists(self, lists, left, right):
        if left >= right:
            return lists[left]
        mid = left + (right - left) // 2
        lino1 = self.__merge_k_lists(lists, left, mid)
        lino2 = self.__merge_k_lists(lists, mid + 1, right)
        return self.__merge_two_sorted_list_node(lino1, lino2)

    def __merge_two_sorted_list_node(self, list1, list2):
        if list1 is None:
            return list2
        if list2 is None:
            return list1
        if list1.val < list2.val:
            list1.next = self.__merge_two_sorted_list_node(list1.next, list2)
            return list1
        else:
            list2.next = self.__merge_two_sorted_list_node(list1, list2.next)
            return list2     

3

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值