隨時找到資料流的中位數

2021-08-16 02:11:48 字數 2197 閱讀 9273

【題目】

有乙個源源不斷地吐出整數的資料流,假設你有足夠的空間來儲存吐出的數。請設計乙個名叫medianholder的結構,medianholder可以隨時取得之前吐出所有數的中位數。

【要求】

1.如果medianholder已經儲存了吐出的n個數,那麼任意時刻將乙個新數加入到medianholder的過程,其時間複雜度是o(logn)。2.取得已經吐出的n個數整體的中位數的過程,時間複雜度為o(1)。

思路:題目要求能隨時取得所有數的中位數,如果採用陣列結構,增加乙個數代價很低o(1),但是不斷增加資料導致陣列需要擴容,本題要求取得所有數的中位數,而每次增加乙個數都要排序,時間複雜度至少o(n*logn),因此不現實。

陣列排序後中間的數為中位數。陣列資料一半劃分到大根堆,一半劃分到小根堆,兩個堆中元素個數和為偶數時,中位數是兩個堆的堆頂相加除以2,兩個堆中元素個數和為奇數時,中位數是堆元素個數多的那個堆頂。此方法沒有排序。怎樣把資料放入到大根堆和小根堆?

建立兩個輔助堆,乙個大根堆,乙個小根堆。我們規定不斷將數放入大根堆,其實也可以不斷往小根堆裡插入。先乙個數(例如5)先往大根堆裡放,然後繼續增加數(例如4),如果加入的數小於大根堆的堆頂(4<5),則將這個數放入到大根堆中,此時大根堆裡有兩個數(5和4)。因為此時小根堆裡的數量為0,如果兩個堆中的數量差值等於2,就將數量多的堆中的乙個數放入到數量少的堆中。該拿哪個數放入另乙個堆中呢?堆頂。這裡要注意:在不斷往堆裡新增數時(heapinsert過程),也要同時調整堆的結構,新增數後仍要保持大根堆或小根堆的結構(heapify過程)。此時小根堆裡有乙個數(5),大根堆裡有乙個數(4),然後再往大根堆裡新增乙個數不斷迴圈這個過程。

時間複雜度:往堆裡插入數的代價為o(logn),poll操作也是o(logn)。

聯想:如果一組數要找出最大數(最小數),並且彈出最大數(最小數)後繼續找出剩餘數的最大數(最小數),考慮堆結構。

**

public class code_01_madianquick 

if (this.minheap.size() == this.maxheap.size() + 2)

} public void addnumber(int num)

if (this.maxheap.peek() >= num) else

if (this.minheap.peek() > num) else

}modifytwoheapssize();

} public integer getmedian()

integer maxheaphead = this.maxheap.peek();

integer minheaphead = this.minheap.peek();

if (((maxheapsize + minheapsize) & 1) == 0)

return maxheapsize > minheapsize ? maxheaphead : minheaphead;

} }public static class maxheapcomparator implements comparator else

} }public static class minheapcomparator implements comparator else

} }// for test

public static int getrandomarray(int maxlen, int maxvalue)

return res;

} // for test, this method is ineffective but absolutely right

public static int getmedianofarray(int arr) else

} public static void printarray(int arr)

system.out.println();

} public static void main(string args)

if (medianhold.getmedian() != getmedianofarray(arr))

} system.out.println(err ? "oops..what a ****!" : "today is a beautiful day^_^");

}}

隨時找到資料流的中位數

題目描述 有乙個源源不斷地吐出整數的資料流,假設你有足夠的空間來儲存吐出的數。請設計乙個名叫medianholder的結構,medianholder可以隨時取得之前吐出所有數的中位數。要求 方法方法1 我們收集到資料之後排序,這樣的時間複雜度就是排序的時間複雜度最好也是o nlogn 無法滿足要求 ...

隨時找到資料流的中位數

有乙個源源不斷的吐出整數的資料流,假設你有足夠的空間來儲存吐出的數。請設計乙個名叫medianholder的結構,medianholder可以隨時取得之前吐出所有數的中位數。要求 1.如果medianholder已經儲存了吐出的n個數,那麼將乙個新數加入到medianholder的過程,其時間複雜度...

隨時找到資料流的中位數

隨時找到資料流的中位數 有乙個源源不斷的吐出整數的資料流,假設你有足夠的空間來儲存吐出的數。請設計乙個名叫medianholder的結構,medianholder可以隨時取得之前吐出所有數的中位數。要求 如果medianholder已經儲存了吐出的n個數,那麼將乙個新數加入到medianholder...