Data Stream Median 81

Question

Numbers keep coming, return the median of numbers at every time a new number added.

Clarification

What's the definition of Median?

  • Median is the number that in the middle of a sorted array. If there are n numbers in a sorted array A, the median is A[(n - 1) / 2]. For example, if A=[1,2,3], median is 2. If A=[1,19], median is 1.

Example

For numbers coming list: [1, 2, 3, 4, 5], return [1, 1, 2, 2, 3].

For numbers coming list: [4, 5, 1, 3, 2, 6, 0], return [4, 4, 4, 3, 3, 3, 3].

For numbers coming list: [2, 20, 100], return [2, 2, 20].

Challenge

Total run time in O(nlogn).

Solution

用一个最大堆(MaxHeap)来存到达的有所元素中较小的一半,用一个最小堆(MinHeap)来存到达的所有元素中较大的一半。每次来一个新的元素就先加入MaxHeap,偶数次加入MaxHeap(不变),奇数次将MaxHeap堆顶元素(最大值)移到MinHeap中。在偶数次时,若MaxHeap堆顶元素(较小一半的最大值)比MinHeap堆顶元素(较大一半的最小值)大,则交换两者位置。median为MaxHeap堆顶元素。

代码如下:

public class Solution {
    /**
     * @param nums: A list of integers.
     * @return: the median of numbers
     */
    private int numberOfElement = 0;
    PriorityQueue<Integer> maxHeap;
    PriorityQueue<Integer> minHeap;

    public int[] medianII(int[] nums) {
        // write your code here
        if(nums == null || nums.length <= 1){
            return nums;
        }
        //重构比较方法,使其从大到小排
        Comparator<Integer> revComp = new Comparator<Integer>(){
            public int compare(Integer left, Integer right){
                return right.compareTo(left);
            }
        };

        int length = nums.length;
        //维护一个最大堆和一个最小堆。
        maxHeap = new PriorityQueue<Integer>(length, revComp);
        minHeap = new PriorityQueue<Integer>(length);

        int[] result = new int[length];
        for(int i = 0; i < length; i++){
            addNumber(nums[i]);
            result[i] = getMedian();
        }

        return result;
    }

    private void addNumber(int value){
        maxHeap.add(value);
        if(numberOfElement % 2 == 0){
            if(minHeap.isEmpty()){
                numberOfElement++;
                return;
            }else{
                if(maxHeap.peek() > minHeap.peek()){
                    Integer maxHeapRoot = maxHeap.poll();
                    Integer minHeapRoot = minHeap.poll();
                    maxHeap.add(minHeapRoot);
                    minHeap.add(maxHeapRoot);
                }
            }
        }else{
            minHeap.add(maxHeap.poll());
        }
        numberOfElement++;
    }

    private int getMedian(){
        return maxHeap.peek();
    }
}

results matching ""

    No results matching ""