問題描述
如何得到一個數據流中的中位數?如果從數據流中讀出奇數個數值,那麼中位數就是所有數值排序之後位於中間的數值。如果從數據流中讀出偶數個數值,那麼中位數就是所有數值排序之後中間兩個數的平均值。我們使用Insert()方法讀取數據流,使用GetMedian()方法獲取當前讀取數據的中位數。
思路
數據流,可能讀取次數非常的多。如果我們insert時不加以區分的加進來,那麼讀取的時候排序就是個很SB的做法。不過這樣也能AC。(方法一)
還有種辦法是,維持一個有序的ArrayList, 怎麼維持?用二分查找來找到插入位置。(其實用LinkedList效率更高哦),不過查找的時候效率就低了。(方法二)
方法一
import java.util.*;
public class Solution {
ArrayList<Integer> mem = new ArrayList<>();
public void Insert(Integer num) {
mem.add(num);
}
public Double GetMedian() {
mem.sort((v1,v2)->v1-v2);
if((mem.size()&1) == 1){
return (double)mem.get(mem.size()/2);
}else{
return ((double)mem.get(mem.size()/2-1)+mem.get(mem.size()/2))/2;
}
}
}
方法二
class Solution {
ArrayList<Integer> mem = new ArrayList<>();
public void Insert(Integer num) {
mem.add(getInsertIndex(num),num);
}
private int getInsertIndex(Integer num){
int left = 0, right = mem.size()-1, mid = left+(right-left)/2;
while(left <= right){
mid = left + (right-left)/2;
if(mem.get(mid) > num) right = mid - 1;
else left = mid + 1;
}
return left;
}
public Double GetMedian() {
if((mem.size()&1) == 1){
return (double)mem.get(mem.size()/2);
}else{
return ((double)mem.get(mem.size()/2-1)+mem.get(mem.size()/2))/2;
}
}
}