堆是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。

1 定义

n个元素序列{k1,k2...ki...kn},当且仅当满足下列关系时称之为堆:
(ki <= k2i, ki <= k2i+1)或者(ki >= k2i, ki >= k2i+1), (i = 1,2,3,4...n/2)

2 性质

堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质。

  • 任意节点小于(或大于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)。
  • 堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。

3 应用

3.1 heapq 模块中的重要函数

>>> import heapq
>>> heapq.__all__
['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', 'nlargest', 'nsmallest', 'heappushpop']
heappush(heap, x)       将 x 入堆
heappop(heap)           将堆属性中的最小元素弹出   
heapify(heap)           将 heap 属性强制应用到任意一个列表
heapreplace(heap, x)    将堆中的最小的元素弹出,同时将 x 入堆
merge()                 多个堆合并         
nlargest(n, iter)       返回 iter 中的第 n 大的元素
nsmallest(n, iter)      返回 iter 中的第 n 小的元素

3.2 创建堆结构

list1 = [3,2,8,1,4,5]
heapq.heapify(list1) list2 = []
heapq.heappush(list2, 3)
heapq.heappush(list2, 2)
heapq.heappush(list2, 8)
heapq.heappush(list2, 1)
heapq.heappush(list2, 4)
heapq.heappush(list2, 5)
list1
Out[110]: [1, 2, 5, 3, 4, 8]
list2
Out[108]: [1, 2, 5, 3, 4, 8]

以上两种方法创建的堆是一样的,元素推入堆后会自动按照二叉树的规范重新排序

3.3 Merge K sorted Lists

用堆的思想合并k个排序链表,并且返回合并后的排序链表。

思路1:

将所有链表的节点 push 到堆中,每次把最小的 pop 出来。代码如下:

"""
Definition of ListNode
class ListNode(object):     def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""
import heapq
class Solution(object):
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        heap = []
        for node in lists:
            while node:
                heapq.heappush(heap, node.val)
                node = node.next
                
        temp = ListNode(-1)
        head = temp
        while heap:
            smallestNode_val = heapq.heappop(heap)
            temp.next = ListNode(smallestNode_val)
            temp = temp.next
        
        return head.next

思路2:

不用堆用列表也能实现,代码如下:

"""
Definition of ListNode
class ListNode(object):     def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
l = []
for node in lists:
while node:
l.append(node.val)
node = node.next
l.sort()
temp = ListNode(-1)
head = temp
for i in l:
temp.next = ListNode(i)
temp = temp.next return head.next

参考资料:

heapq — Heap queue algorithm

python 中的堆 (heapq 模块)应用:Merge K Sorted Lists的更多相关文章

  1. [Leetcode][Python]23: Merge k Sorted Lists

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 23: Merge k Sorted Listshttps://oj.leet ...

  2. 蜗牛慢慢爬 LeetCode 23. Merge k Sorted Lists [Difficulty: Hard]

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

  3. Merge k Sorted Lists

    1. Merge Two Sorted Lists 我们先来看这个 问题: Merge two sorted linked lists and return it as a new list. The ...

  4. LeetCode: Merge k Sorted Lists 解题报告

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  5. Leetcode 23.Merge Two Sorted Lists Merge K Sorted Lists

    Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list shoul ...

  6. Merge k Sorted Lists——分治与堆排序(需要好好看)

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

  7. 71. Merge k Sorted Lists

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  8. 【leetcode】Merge k Sorted Lists

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

  9. 【LeetCode练习题】Merge k Sorted Lists

    Merge k Sorted Lists Merge k sorted linked lists and return it as one sorted list. Analyze and descr ...

随机推荐

  1. oracle 创建自定义的流水号

    ; --你确定流水号只要3位? 使用它的下一个值用: seq_abc_taskid.nextval查询当前值用:seq_abc_taskid.currval比如你现在要插入一行到abc,你可以 ,se ...

  2. git如何merge github forked repository里的代码更新?(转)

    参考内容:git如何merge github forked repository里的代码更新? [refer to ]http://www.haojii.com/2011/08/how-to-git- ...

  3. html中传递信息

    <div class="card" data-username="ArgenBarbie"> </div> JS: var userna ...

  4. Pandas初学者代码优化指南

    原文:A Beginner’s Guide to Optimizing Pandas Code for Speed 作者:Sofia Heisler 翻译:无阻我飞扬 摘要:Pandas 是Pytho ...

  5. Tomcat修改版本号教程(CentOS)

    1 到apache-tomcat安装目录下的lib子文件夹,找到catalina.jar备份该文件然后将该文件下载到本地. 2 使用winrar等工具直接打开该jar包进入到org/apache/ca ...

  6. python删除指定路径的文件

    import os            import glob                        path =imgDate_listResult            for infi ...

  7. 重绘(Repaint)和回流(Reflow)

    重绘(Repaint)和回流(Reflow) 1.回流和重绘只是渲染步骤的一小节,是怎么做到影响性能的? css 会影响 javascrip 执行时间导致 javascript 脚本变慢 浏览器渲染一 ...

  8. Jenkins结合testng注意事项

    1.在生成测试报告时,因为Jenkins自带的只有Junit的测试报告,不会显示testng的. 2.要想显示Publish TestNG Results这一项,首先需要在jenkins的首页-系统管 ...

  9. API服务网关(Zuul)

    技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡,那我们的各种微服务又要如何提供给外部应用调用呢. 当然,因为是REST API接口,外部客户端直接调用各个微服务是没有问 ...

  10. day21-python操作mysql1

    python的mysql操作 mysql数据库是最流行的数据库之一,所以对于python操作mysql的了解是必不可少的.Python标准数据库接口为Python DB-API, Python DB- ...