Median in BM48 data stream

describe

How to get the median in a data stream? If an odd number of values ​​are read from the data stream, the median is the value in the middle of all values ​​sorted. If an even number of values ​​are read from the data stream, the median is the average of the middle two numbers after all the values ​​are sorted. We use the Insert() method to read the data stream, and use the GetMedian() method to get the median of the currently read data.

Data range: The number of numbers in the data stream satisfies 1≤n≤1000, and the size satisfies 1≤val≤1000 

Advanced: Space complexity \O(n), time complexity O(nlogn) 

Example 1

enter:

[5,2,3,4,1,6,7,0,8]

return value:

"5.00 3.50 3.00 3.50 3.00 3.50 4.00 3.50 4.00 "

illustrate:

5, 2, 3... are continuously spit out in the data stream, and the average numbers obtained are 5, (5+2)/2, 3...   

Example 2

enter:

[1,1,1]

return value:

"1.00 1.00 1.00 "

Method 1 (violent sorting solution)

The sorting method uses insertion sort

Maintain a sequential array. If a number comes, compare it with the right side of the current array and insert it into the appropriate position

import java.util.*;
public class Solution {
    ArrayList<Integer> list =new ArrayList<>();
    public void Insert(Integer num) {
//         list.add(num);
//         Collections.sort(list);  //或者调用库函数直接排序
        if(list.size()==0){   //如果list为空
            list.add(num);   //list是存储已经排好的顺序序列
            return;
        }
        int i;
        for(i=list.size()-1;i>=0;i--){
          if(list.get(i)<num){  //如果list当前的元素大于num,list插入元素不需要移动后面元素
              list.add(i+1,num);  //则把他放置到该list元素的前面,保证顺序序列
              return;
          }
        }
        //此时i=-1
        list.add(i+1,num);    //说明该list全部大于num,则把num放到list最前面,不需要移动元素,已经封装好了
    }

    public Double GetMedian() {
        if(list.size()%2==1){
            int t=list.size()/2;
            Double d=list.get(t)/1.0;
            return d;
        }
        else{
            int t=list.size()/2;
            Double d=(list.get(t)+list.get(t-1))/2.0;
            return d;
        }
    }


}

Method 2 (one large root pile and one small root pile)

Heap sorting, big top heap and small top heap are the optimal algorithms

(Heap sort)
Let the first half of the array be a big top heap, requiring the maximum value. The second half is the small top heap, and the minimum value is required
. The even number is the same number on both sides. When taking the average odd number of the maximum value of the large top heap and the minimum value of the small top heap,
the number on the right side is increased by one, and the minimum value of the small top heap is taken directly. Values ​​are sufficient
since all values ​​on the left are smaller than those on the right. So if you want to insert to the left, you need to insert into the small top pile on the right first, and then pop out the smallest one and add it to the left. vice versa

import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {
    PriorityQueue<Integer> min_heap=new PriorityQueue<>();
    PriorityQueue<Integer> max_heap=new PriorityQueue<>(new Comparator<Integer>(){
        @Override
        public int compare(Integer o1,Integer o2){
            return o2-o1;//默认是小顶堆,o1-o2
        }
    });
    int count=0;//记录已获取数字的个数
    public void Insert(Integer num) {
        if(count%2==0){
            max_heap.offer(num);
            int tmp=max_heap.poll();
            min_heap.offer(tmp);
        }
        else{
            min_heap.offer(num);
            int tmp=min_heap.poll();
            max_heap.offer(tmp);
        }
        count++;
    }

    public Double GetMedian() {
        if(count%2==0){
            return new Double(min_heap.peek()+max_heap.peek())/2;
        }
        else{
            return new Double(min_heap.peek());
        }
    }


}

Guess you like

Origin blog.csdn.net/hgnuxc_1993/article/details/124080979