当前位置: 首页 > news >正文

优先级队列 模版题单

优先级队列 (堆)

用到优先级队列 (priority queue) 或堆 (heap) 的题一般需要维护一个动态更新的池,元素会被频繁加入到池中或从池中被取走,每次取走的元素为池中优先级最高的元素 (可以简单理解为最大或者最小)。
用堆来实现优先级队列是效率非常高的方法,加入或取出都只需要 O(log N) 的复杂度
Python的heapq模块实现了一个最小堆(小顶堆),底层基于**二叉堆(Binary Heap)**数据结构。以下是其核心实现原理和常用操作的时间复杂度分析:

底层实现原理

  1. 二叉堆结构

    • heapq使用完全二叉树实现堆,即除了最后一层外,每一层都被完全填充,且最后一层的节点从左到右排列。
    • 堆的特性:每个节点的值都小于或等于其子节点的值(最小堆)。
  2. 数组存储

    • 堆以一维数组形式存储,通过索引计算父子关系:
      • 节点i的左子节点:2i + 1
      • 节点i的右子节点:2i + 2
      • 节点i的父节点:(i - 1) // 2
  3. 核心操作

    • 上浮(Heapify Up):插入元素时,新元素从数组末尾开始向上调整,直到满足堆性质。
    • 下沉(Heapify Down):删除堆顶元素后,将最后一个元素移到堆顶,然后向下调整,直到满足堆性质。

常用操作的时间复杂度

操作时间复杂度说明
heapq.heappush(h, x)O(log n)插入元素到堆中,需执行上浮操作调整堆结构。
heapq.heappop(h)O(log n)删除并返回堆顶元素,需执行下沉操作调整堆结构。
heapq.heapify(x)O(n)将列表转换为堆,通过从最后一个非叶子节点开始下沉调整,效率高于逐个插入。
h[0]O(1)访问堆顶元素(最小值)。

关键代码实现(简化版)

以下是heapq核心操作的简化实现,帮助理解原理:

def heappush(heap, item):heap.append(item)_siftup(heap, len(heap) - 1)  # 上浮操作def heappop(heap):lastelt = heap.pop()if heap:returnitem = heap[0]heap[0] = lastelt_siftdown(heap, 0)  # 下沉操作return returnitemreturn lasteltdef _siftup(heap, pos):# 上浮:从pos位置开始向上调整newitem = heap[pos]while pos > 0:parentpos = (pos - 1) // 2parent = heap[parentpos]if newitem < parent:heap[pos] = parentpos = parentposcontinuebreakheap[pos] = newitemdef _siftdown(heap, pos):# 下沉:从pos位置开始向下调整startpos = posnewitem = heap[pos]childpos = 2 * pos + 1while childpos < len(heap):rightpos = childpos + 1if rightpos < len(heap) and not heap[childpos] < heap[rightpos]:childpos = rightposheap[pos] = heap[childpos]pos = childposchildpos = 2 * pos + 1heap[pos] = newitem_siftup(heap, pos)  # 最后可能需要上浮微调

应用场景

  • 优先队列:任务调度、Dijkstra算法等。
  • Top-K问题:求最大/最小的K个元素。
  • 合并有序序列:多路归并排序。

总结

heapq通过数组实现二叉堆,保证插入和删除操作的时间复杂度为O(log n),适合处理动态数据集合。其设计巧妙,无需显式维护树结构,通过数组索引即可高效操作,是Python中处理堆相关问题的标准库。

Kth largest/smallest

找数据中第 K 个最大/最小数据是堆的一个典型应用。以找最大为例,遍历数据时,使用一个最小堆来维护当前最大的 K 个数据,堆顶数据为这 K 个数据中最小,即是你想要的第 k 个最大数据。每检查一个新数据,判断是否大于堆顶,若大于,说明堆顶数据小于了 K 个值,不是我们想找的第 K 个最大,则将新数据 push 进堆并 pop 掉堆顶,若小于则不操作,这样当遍历完全部数据后堆顶即为想要的结果。找最小时换成最大堆即可。

kth-largest-element-in-a-stream

设计一个找到数据流中第K大元素的类。

import heapqclass Item:def __init__(self, value):self.value = value# 定义小于比较,使堆变成最大堆def __lt__(self, other):return self.value > other.value  # 反向比较max_heap = []
heapq.heappush(max_heap, Item(3))
heapq.heappush(max_heap, Item(1))
heapq.heappush(max_heap, Item(4))# 弹出时取 value
print(heapq.heappop(max_heap).value)  # 输出: 4
print(heapq.heappop(max_heap).value)  # 输出: 3
import heapq# 创

相关文章:

  • YOLOv8源码修改(5)- YOLO知识蒸馏(下)设置蒸馏超参数:以yolov8-pose为例
  • [C++] 洛谷B3959(GESP2024三月四级)做题
  • LLM多平台统一调用系统-LiteLLM概述
  • C++ 中的引用参数(Reference Parameter)‌
  • 【DeepSeek】计算机科学与技术专业的学习顺序
  • Vue3编译器:静态提升原理
  • 【Simulink】IEEE5/IEEE9/IEEE14/IEEE30/IEEE33/IEEE39仿真模型
  • 【Day36】
  • openjdk底层(hotspot)汇编指令的内存分布
  • 关于多类型数据划分清洗的整理
  • ISO 20000体系:服务请求管理、问题管理、事件管理区别与联系
  • BAT32G113 发送互补PWM
  • 第十九章:数据治理之数据指标(一):数据指标工具之【指标口径管理系统】与【指标数据查询系统】
  • (九)PMSM驱动控制学习---无感控制之高阶滑膜观测器
  • obsidian 中的查找和替换插件,支持正则
  • STL-从list节点创建和释放展开(内存管理)
  • Linux系统编程-DAY04
  • C语言初阶--操作符
  • 升级Win11后VMware虚拟机屏幕调整问题
  • 领域驱动设计与COLA框架:从理论到实践的落地之路
  • 佛山网站制作专家/seo是怎么优化
  • 山东建设工程上传原件的网站/网络推广十大平台
  • 福建路桥建设有限公司网站/网络推广赚钱平台有哪些
  • 网站建设评审/网站视频
  • 深圳住建网站/百度服务电话
  • 网站建设项目申请/查域名备案