当前位置:  首页>> 技术小册>> 数据结构与算法(下)

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

解法

利用大根堆存放较小的一半元素,小根堆存放较大的一半元素。维持大小堆的元素个数差不超过 1。

  1. import java.util.Comparator;
  2. import java.util.PriorityQueue;
  3. /**
  4. * @author bingo
  5. * @since 2018/12/7
  6. */
  7. public class Solution {
  8. private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
  9. private PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
  10. /**
  11. * 插入一个数
  12. *
  13. * @param num 数
  14. */
  15. public void Insert(Integer num) {
  16. if (maxHeap.isEmpty() || num < maxHeap.peek()) {
  17. maxHeap.offer(num);
  18. if (maxHeap.size() - minHeap.size() > 1) {
  19. minHeap.offer(maxHeap.poll());
  20. }
  21. } else {
  22. minHeap.offer(num);
  23. if (minHeap.size() - maxHeap.size() > 1) {
  24. maxHeap.offer(minHeap.poll());
  25. }
  26. }
  27. }
  28. /**
  29. * 获取中位数
  30. *
  31. * @return 中位数
  32. */
  33. public Double GetMedian() {
  34. int size1 = maxHeap.size();
  35. int size2 = minHeap.size();
  36. if (size1 > size2) {
  37. return (double) maxHeap.peek();
  38. }
  39. if (size1 < size2) {
  40. return (double) minHeap.peek();
  41. }
  42. return (maxHeap.peek() + minHeap.peek()) / 2.0;
  43. }
  44. }

测试用例

  1. 功能测试(从数据流中读出奇数/偶数个数字);
  2. 边界值测试(从数据流中读出 0/1/2 个数字)。

该分类下的相关小册推荐: