Problem

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 isA[(n - 1) / 2]. For example, ifA=[1,2,3], median is2. IfA=[1,19], median is1.

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].

思路一(暴力)

  • 每次来一个数, 我们就排序, 然后输出
  • 时间复杂度: O(n * nlogn)
  • 空间复杂度: O(1)
    public int[] medianII(int[] nums) {
        if (nums == null || nums.length == 0) {
            return new int[0];
        }
        int[] res = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            Arrays.sort(nums, 0, i + 1);
            res[i] = nums[i / 2];
        }
        return res;
    }

思路二(heap)

  • 优化思路:
    • heap能令每次进来的数据都有序, 并且每次操作为O(logn)
    • 问题: 如何如何用O(1)或者用O(n)的时间内从heap中找到median ?
      • 用两个heap:
        • maxheap: 存前半部分数据
        • minheap: 存后半部分数据
        • max in maxheap <= min in minheap
      • 容易出错的点:
        • 一个incoming的元素, 必须要先存到maxheap, 然后将maxheap的最大值存到minheap中. 避免这个incoming元素大于minheap的最小值
    public int[] medianII(int[] nums) {
        if (nums == null || nums.length == 0) {
            return new int[0];
        }
        int[] res = new int[nums.length];
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(1, Collections.reverseOrder());

        for (int i = 0; i < nums.length; i++) {
            maxHeap.offer(nums[i]);
            minHeap.offer(maxHeap.poll());
            if (minHeap.size() > maxHeap.size()) {
                maxHeap.offer(minHeap.poll());
            }
            res[i] = maxHeap.peek();
        }
        return res;
    }

Follow up: Sliding window Median

results matching ""

    No results matching ""