【python】中位数(暴力+最大最小堆)
题目:
"""
对给定长度为N的非负整数序列A,计算前奇数项的中位数。
输入:首行表示序列长度N。次行为N个正整数A1至AN。
输出:输出共(N+1)/2行(向下取整),第i行表示到第A1...2i-1项的中位数。
"""
暴力解法:
n = int(input())
a = list(map(int, input().split()))
b = []
# 遍历输入序列的每个元素
for i in range(1, n + 1):
# 将当前元素添加到逐步增长的序列中
b.append(a[i - 1])
# 对逐步增长的序列进行排序,以便后续找中位数
b.sort()
# 当序列长度为奇数时,输出当前的中位数
if i % 2 == 1:
print(b[i // 2])
最大+最小堆:
# heapq 模块,它提供了堆操作的基本功能,比如插入元素和删除最小元素。
import heapqn = int(input())
a = list(map(int, input().split()))
# 我们的目标是保持 max_heap 的大小比 min_heap 的大小大1,这样 max_heap 的根节点就是中位数。
# 最大堆用于存储较小的一半数字,最小堆存储较大的一半数字
max_heap, min_heap = [], []for i in range(n):# 将数字加入到堆中# 如果 max_heap 为空或当前数字小于或等于 max_heap 的最大元素(-max_heap[0] 是 max_heap 的最大元素,因为我们用负数来模拟最大堆),则将该数字插入 max_heap。否则,将其插入 min_heap。if not max_heap or a[i] <= -max_heap[0]:heapq.heappush(max_heap, -a[i])else:heapq.heappush(min_heap, a[i])# 保持两个堆的大小平衡# 这两个循环确保了两个堆的大小保持平衡。如果 max_heap 的大小比 min_heap 的大小大2或更多,就从 max_heap 中移除最大元素并将其插入 min_heap。如果 min_heap 的大小比 max_heap 的大小大,就从 min_heap 中移除最小元素并将其插入 max_heap。while len(max_heap) > len(min_heap) + 1:heapq.heappush(min_heap, -heapq.heappop(max_heap))while len(min_heap) > len(max_heap):heapq.heappush(max_heap, -heapq.heappop(min_heap))# 如果当前是奇数项,输出中位数if i % 2 == 0:print(-max_heap[0])