劍指Offer刷題筆記 資料流中的中位數

2021-09-26 09:00:17 字數 1289 閱讀 9721

如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用insert()方法讀取資料流,使用getmedian()方法獲取當前讀取資料的中位數。

主要思想:

最大堆 | 最小堆

我們將資料分為兩部分,位於左邊最大堆的資料比右邊最小堆的資料要小,左、右兩邊內部的資料沒有排序,也可以根據左邊最大的數及右邊最小的數得到中位數。

接下來考慮用最大堆和最小堆實現的一些細節。

首先要保證資料平均分配到兩個堆中

此外,還要保證最大堆中所有資料小於最小堆中資料。所以,新傳入的資料需要先和最大堆的最大值或者最小堆中的最小值進行比較。以總數目為偶數為例,按照我們制定的規則,新的資料會被插入到最小堆中,但是在這之前,我們需要判斷這個資料和最大堆中的最大值誰更大,如果最大堆中的資料比較大,那麼我們就需要把當前資料插入最大堆,然後彈出新的最大值,再插入到最小堆中。由於最終插入到最小堆的數字是原最大堆中最大的數字,這樣就保證了最小堆中所有數字都大於最大堆的數字。

large是小根堆,儲存的是整個資料流裡數值大的一半數。

small是大根堆,但是heapq預設是小根堆,可以用給所有數值取負數的方法,使得變成大根堆。small儲存的是資料流裡小的一半資料。

# -*- coding:utf-8 -*-

from heapq import *

class solution:

def __init__(self):

self.heaps = ,

def insert(self, num):

# write code here

small, large = self.heaps

# 就是要保證large的長度不小於small

# 否則第乙個資料進入large就又進入small了,large就一直為空。

if len(large) < len(small):

def getmedian(self,ss):

# write code here

small,large = self.heaps

# 說明這個資料流裡有奇數個數值

if len(large) > len(small):

return float(large[0])

return (large[0] - small[0]) /2.0

劍指offer刷題筆記

給定一顆二叉搜尋樹,請找出其中的第k大的結點。例如,5 3 7 2 4 6 8 中,按結點數值大小順序第三個結點的值為4。struct treenode class solution treenode kthnode treenode proot,int k 非遞迴實現 class solution...

劍指offer 資料流中的中位數

題目描述 如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。實現 public class getmediannum listnode in new listnod...

劍指Offer 資料流中的中位數

題目描述 如何得到乙個資料流中的中位數?如果從資料流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從資料流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。思路整理 這個題目要解出來很簡單,但是這裡有乙個比較好的思路 用最大和最小堆來實現,就像乙個沙漏一樣,上...