【題目】
有乙個源源不斷地吐出整數的資料流,假設你有足夠的空間來儲存吐出的數。請設計乙個名叫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...