41、資料流中的中位數
阿新 • • 發佈:2019-01-05
思路:
前一半數用最大堆儲存,後一半數用最小堆儲存,並且最大堆的所有數小於最小堆的所有數,這樣求中位數就是當最大堆最小堆堆頂的和的一半。
import java.util.ArrayList;
public class Solution {
ArrayList<Integer> max = new ArrayList<Integer>();
ArrayList<Integer> min = new ArrayList<Integer>();
//插入資料流來的數
public void Insert(Integer num) {
if(max.size()==0)
max.add(0);
if(min.size()==0)
min.add(0);
//看是向哪個堆新增資料
if(max.size()==min.size())
{
if((min.size()==1)||(num<=min.get(1)))
insertMax(max,num);
else{
insertMax(max ,min.get(1));
min.remove(1);
insertMin(min,num);
}
}
else{
if((max.size()==1)||(num>=max.get(1)))
insertMin(min,num);
else{
insertMin(min,max.get(1));
max.remove(1);
insertMax(max ,num);
}
}
}
//得到中位數
public Double GetMedian() {
if((max.size()==1)&&(min.size()==1))
return 0.0;
else if((max.size()+min.size())%2==1)
return (double)max.get(1);
else
return ((double)(max.get(1)+min.get(1)))/2.0;
}
//交換兩數
public void swap(ArrayList<Integer> a,int p1,int p2)
{
int temp = a.get(p1);
a.set(p1,a.get(p2));
a.set(p2,temp);
}
//在最大堆中新增數
public void insertMax(ArrayList<Integer> max,Integer num)
{
int i = max.size();
max.add(num);
while((i>1)&&(max.get(i)>max.get(i/2)))
{
swap(max,i,i/2);
i=i/2;
}
}
//在最小堆中新增數
public void insertMin(ArrayList<Integer> min,Integer num)
{
int i = min.size();
min.add(num);
while((i>1)&&(min.get(i)<min.get(i/2)))
{
swap(min,i,i/2);
i=i/2;
}
}
}