Running Median(动态维护中位数问题,对顶堆)

题面:Running Median题目大意顺序输入 nnn 个数,当下标为奇数时,就输出一次当前序列的中位数。例如,当遍历或输入到第 iii 个数时,iii 恰好为奇数,则就要在序列 a[1]a[1]a[1] 到 a[i]a[i]a[i] 之间找到一个中位数,并输出出来。思路这题是对顶堆的板子题。用两个小根堆和大根堆来动态维护序列。其中,大根堆维护较小的一半元素,小根堆维护较大的一半元素。即:序列中从小到大次序为 [1,len/2][1,len/2][1,len/2] 的整数存储在大根堆中
摘要由CSDN通过智能技术生成
题面:Running Median
题目大意

顺序输入 n n n 个数,当下标为奇数时,就输出一次当前序列的中位数。
例如,当遍历或输入到第 i i i 个数时, i i i 恰好为奇数,则就要在序列 a [ 1 ] a[1] a[1] a [ i ] a[i] a[i] 之间找到一个中位数,并输出出来。

思路

这题是对顶堆的板子题。用两个小根堆和大根堆来动态维护序列。
其中,大根堆维护较小的一半元素,小根堆维护较大的一半元素。
即:

  1. 序列中从小到大次序为 [ 1 , l e n / 2 ] [1,len/2] [1,len/2] 的整数存储在大根堆中。
  2. 序列中从小到大次序为 [ l e n / 2
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是中位数问题的分治法伪代码: ``` def find_median(nums): n = len(nums) if n % 2 == 1: # 如果数组元素个数是奇数 return quick_select(nums, n // 2) # 直接找到第 n//2 小的元素即为中位数 else: # 如果数组元素个数是偶数 return (quick_select(nums, n // 2 - 1) + quick_select(nums, n // 2)) / 2 # 找到第 n//2 - 1 小和第 n//2 小的元素,取平均值作为中位数 def quick_select(nums, k): if len(nums) == 1: # 如果只有一个元素,则返回该元素 return nums[0] pivot = random.choice(nums) # 随机选择一个枢轴元素 left = [x for x in nums if x < pivot] # 将小于枢轴的元素放到左边数组 right = [x for x in nums if x > pivot] # 将大于枢轴的元素放到右边数组 mid = [x for x in nums if x == pivot] # 将等于枢轴的元素放到中间数组 if k < len(left): # 如果第 k 小的元素在左边数组中,递归处理左边数组 return quick_select(left, k) elif k < len(left) + len(mid): # 如果第 k 小的元素在中间数组中,直接返回中间数组的第一个元素 return mid[0] else: # 如果第 k 小的元素在右边数组中,递归处理右边数组 return quick_select(right, k - len(left) - len(mid)) ``` 其中,`quick_select` 函数用于找到第 k 小的元素,`find_median` 函数用于找到数组的中位数。在 `find_median` 函数中,如果数组元素个数是奇数,则直接找到第 n//2 小的元素即为中位数;如果数组元素个数是偶数,则找到第 n//2 - 1 小和第 n//2 小的元素,取平均值作为中位数

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值