LeetCode23:Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

LeetCode:链接

使用堆这一数据结构,首先将每条链表的头节点进入堆中,然后将最小的弹出,并将最小的节点这条链表的下一个节点入堆,依次类推,最终形成的链表就是归并好的链表。

heapq使用说明:

a为普通列表 
- heapq.heapify(a) 调整a,使得其满足最小堆 
- heapq.heappop(a) 从最小堆中弹出最小的元素 ,弹出仍然是一个最小堆
- heapq.heappush(a,b) 向最小堆中压入新的元素,压入仍然是一个最小堆

如果传进元组,第一个元素必须是要比较的值!

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

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        # 定义一个最小堆
        heap = []
        for l in lists:
            # 必须判断是否为空
            if l:
                heap.append((l.val, l))
        # 调整heap使之成为一个最小堆
        heapq.heapify(heap)
        head = ListNode(0)
        dummy = head
        while heap:
            # 弹出最小元素
            _, cur = heapq.heappop(heap)
            dummy.next = cur
            dummy = dummy.next
            # 向最小堆中压入新的元素
            if cur.next:
                heapq.heappush(heap, (cur.next.val, cur.next))
        return head.next

自己实现堆的结构,修改了好多次,终于a过去了。需要注意的是:

1)堆保存的是(结点值,结点)的元组,但是进行HeadAdjust的时候,比较的是第一个元素结点值,而调整的是第二个元素结点。

2)如果选出的最小结点有next,就插入到最小堆的0位置;如果选出的最小结点没有next,仍然得进行堆调整,此时就是把堆的最后一个元素插入到0位置。但是必须此时堆中的元素个数要大于1

3)使用pop和insert的方法对堆进行调整,直接赋值会TLE。

4)如果每次都用建堆的方法调整,肯定可以,但是会TLE。

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

class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        heap = []
        for l in lists:
            # 必须不为空才能加入heap中
            if l:
                heap.append((l.val, l))
        length = len(heap)
        for i in range(0, length//2)[::-1]:
            self.HeadAdjust(heap, i, length)
        head = ListNode(0)
        dummy = head
        while heap:
            _, cur = heap.pop(0)
            dummy.next = cur
            dummy = dummy.next
            if cur.next:
                heap.insert(0, (cur.next.val, cur.next))
                self.HeadAdjust(heap, 0, len(heap))             
            else:
                if len(heap) >= 1:
                    heap.insert(0, heap.pop())
                    self.HeadAdjust(heap, 0, len(heap))                          
        return head.next

    def HeadAdjust(self, input_list, parent, length):
        cur = input_list[parent]
        temp = input_list[parent][0]
        child = 2 * parent + 1
        while child < length:
            if child + 1 < length and input_list[child+1][0] < input_list[child][0]:
                child += 1
            if temp <= input_list[child][0]:
                break
            input_list[parent] = input_list[child]
            parent = child
            child = 2 * parent + 1
        input_list[parent] = cur
        return input_list

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值