Array - 295. Find Median from Data Stream

时间:2022-07-25
本文章向大家介绍Array - 295. Find Median from Data Stream,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

295. Find Median from Data Stream

Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

For example,

[2,3,4], the median is 3

[2,3], the median is (2 + 3) / 2 = 2.5

Design a data structure that supports the following two operations:

  • void addNum(int num) - Add a integer number from the data stream to the data structure.
  • double findMedian() - Return the median of all elements so far.

Example:

addNum(1) addNum(2) findMedian() -> 1.5 addNum(3) findMedian() -> 2

Follow up:

  1. If all integer numbers from the stream are between 0 and 100, how would you optimize it?
  2. If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?

思路:

这题是实现几个接口,保证接口可以找出数据流的中位数,bf肯定是可以做,但是更好的解法就是使用两个堆或者优先队列,只要找出两个堆的根元素,也就是小根堆的堆顶和大根堆的堆顶元素,两数之和的一半就是中位数。还可以使用bst来做,两个左右指针,来确定中位数。

代码:

java:

class MedianFinder {
     
    PriorityQueue<Integer> min = null;
    PriorityQueue<Integer> max = null;
    
    /** initialize your data structure here. */
    public MedianFinder() {
        min = new PriorityQueue();
        max = new PriorityQueue(10, Collections.reverseOrder());
    }
    
    public void addNum(int num) {
        max.offer(num);
        min.offer(max.poll());
        if (max.size() < min.size()) max.offer(min.poll());
    }
    
    public double findMedian() {
        if (max.size() == min.size()) return (max.peek() + min.peek()) / 2.0;
        else return max.peek();
    }
}
    
/*class MedianFinder {
    ArrayList<Integer> nums;

    public int findInsertIndex(int target) {
        int low = 0;
        int high = nums.size() - 1;

        while (low <= high) {
            int mid = (low + high) / 2;

            if (nums.get(mid) >= target)
                high = mid - 1;
            else
                low = mid + 1;
        }

        return low;
    }

    public MedianFinder() {
        nums = new ArrayList<>();
    }

    public void addNum(int num) {
        if (nums.size() == 0) {
            nums.add(num);
        } else {
            int index = findInsertIndex(num);
            if (index == nums.size()) {
                nums.add(num);
            } else {
                nums.add(index, num);
            }
        }
    }

    public double findMedian() {
        int mid = (nums.size() - 1) / 2;
        return nums.size() % 2 == 0 ? (nums.get(mid) + nums.get(mid + 1)) / 2.0 : nums.get(mid);
    }
}*/