Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java

Google面试题

股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值)。

SOLUTION 1:

1.维持两个heap,一个是最小堆,一个是最大堆。

2.一直使maxHeap的size大于minHeap.

3. 当两边size相同时,比较新插入的value,如果它大于minHeap的最大值,把它插入到minHeap。并且把minHeap的最小值移动到maxHeap。

...具体看代码

技术分享
 1 /**************************************************************
 2  * 
 3  * 08-722 Data Structures for Application Programmers
 4  * Lab 7 Heaps and Java PriorityQueue class
 5  * 
 6  * Find median of integers using Heaps (maxHeap and minHeap)
 7  * 
 8  * Andrew id:  yuzhang
 9  * Name: Yu Zhang
10  * 
11  **************************************************************/
12 
13 import java.util.*;
14 
15 public class FindMedian {
16     private static PriorityQueue<Integer> maxHeap, minHeap;
17 
18     public static void main(String[] args) {
19 
20         Comparator<Integer> revCmp = new Comparator<Integer>() {
21             @Override
22             public int compare(Integer left, Integer right) {
23                 return right.compareTo(left);
24             }
25         };
26 
27         // Or you can use Collections‘ reverseOrder method as follows.
28         // Comparator<Integer> revCmp = Collections.reverseOrder();
29 
30         maxHeap = new PriorityQueue<Integer>(20, revCmp);
31         minHeap = new PriorityQueue<Integer>(20);
32 
33         addNumber(6);
34         addNumber(4);
35         addNumber(3);
36         addNumber(10);
37         addNumber(12);
38         System.out.println(minHeap);
39         System.out.println(maxHeap);
40         System.out.println(getMedian());
41 
42         addNumber(5);
43         System.out.println(minHeap);
44         System.out.println(maxHeap);
45         System.out.println(getMedian());
46 
47         addNumber(7);
48         addNumber(8);
49         System.out.println(minHeap);
50         System.out.println(maxHeap);
51         System.out.println(getMedian());
52     }
53 
54     /*
55      * Note: it maintains a condition that maxHeap.size() >= minHeap.size()
56      */
57     public static void addNumber(int value) {
58         if (maxHeap.size() == minHeap.size()) {
59             if (minHeap.peek() != null && value > minHeap.peek()) {
60                 maxHeap.offer(minHeap.poll());
61                 minHeap.offer(value);
62             } else {
63                 maxHeap.offer(value);
64             }
65         } else {
66             if (value < maxHeap.peek()) {
67                 minHeap.offer(maxHeap.poll());
68                 maxHeap.offer(value);
69             } else {
70                 minHeap.offer(value);
71             }
72         }
73     }
74 
75     /*
76      * If maxHeap and minHeap are of different sizes, 
77      * then maxHeap must have one extra element.
78      */
79     public static double getMedian() {
80         if (maxHeap.isEmpty()) {
81             return -1; 
82         }
83         
84         if (maxHeap.size() == minHeap.size()) {
85             return (double)(minHeap.peek() + maxHeap.peek())/2;
86         } else {
87             return maxHeap.peek();
88         }
89     }
90 }
View Code

 

SOLUTION 2:

比起solution 1 ,进行了简化

1.无论如何,直接把新值插入到maxHeap。

2. 当minHeap为空,直接退出。

3. 当maxHeap比minHeap多2个值,直接移动一个值到maxHeap即可。

4. 当maxHeap比minHeap多1个值,比较顶端的2个值,如果maxHeap的最大值小于minHeap的最小值,交换2个值即可。

5. 当maxHeap较大时,中值是maxHeap的顶值,否则取2者的顶值的中间值。

技术分享
  1 /**************************************************************
  2  * 
  3  * 08-722 Data Structures for Application Programmers
  4  * Lab 7 Heaps and Java PriorityQueue class
  5  * 
  6  * Find median of integers using Heaps (maxHeap and minHeap)
  7  * 
  8  * Andrew id:  yuzhang
  9  * Name: Yu Zhang
 10  * 
 11  **************************************************************/
 12 
 13 import java.util.*;
 14 
 15 public class FindMedian_20150122 {
 16     private static PriorityQueue<Integer> maxHeap, minHeap;
 17 
 18     public static void main(String[] args) {
 19         // Or you can use Collections‘ reverseOrder method as follows.
 20         // Comparator<Integer> revCmp = Collections.reverseOrder();
 21 
 22         maxHeap = new PriorityQueue<Integer>(20, new Comparator<Integer>(){
 23             public int compare(Integer o1, Integer o2) {
 24                 return o2 - o1;
 25             }
 26         });
 27         
 28         minHeap = new PriorityQueue<Integer>(20);
 29 
 30         addNumber(6);
 31         addNumber(4);
 32         addNumber(3);
 33         addNumber(10);
 34         addNumber(12);
 35         System.out.println(minHeap);
 36         System.out.println(maxHeap);
 37         System.out.println(getMedian());
 38 
 39         addNumber(5);
 40         System.out.println(minHeap);
 41         System.out.println(maxHeap);
 42         System.out.println(getMedian());
 43 
 44         addNumber(7);
 45         addNumber(8);
 46         System.out.println(minHeap);
 47         System.out.println(maxHeap);
 48         System.out.println(getMedian());
 49     }
 50 
 51     /*
 52      * Note: it maintains a condition that maxHeap.size() >= minHeap.size()
 53      */
 54     public static void addNumber1(int value) {
 55         if (maxHeap.size() == minHeap.size()) {
 56             if (!maxHeap.isEmpty() && value > minHeap.peek()) {
 57                 // put the new value in the right side.
 58                 maxHeap.offer(minHeap.poll());
 59                 minHeap.offer(value);
 60             } else {
 61                 // add the new value into the left side.
 62                 maxHeap.offer(value);
 63             }
 64         } else {
 65             if (value < maxHeap.peek()) {
 66                 // add the new value into the left side.
 67                 minHeap.offer(maxHeap.poll());
 68                 maxHeap.offer(value);
 69             } else {
 70                 // add the new value into the right side.
 71                 minHeap.offer(value);
 72             }
 73         }
 74     }
 75     
 76     /*
 77      * Note: it maintains a condition that maxHeap.size() >= minHeap.size()
 78      * solution 2:
 79      */
 80     public static void addNumber(int value) {
 81         maxHeap.offer(value);
 82         
 83         // For this case, before insertion, max-heap has n+1 and min-heap has n elements.  
 84         // After insertion, max-heap has n+2 and min-heap has n elements, so violate!  
 85         // And we need to pop 1 element from max-heap and push it to min-heap  
 86         if (maxHeap.size() - minHeap.size() == 2) {
 87             // move one to the right side.
 88             minHeap.offer(maxHeap.poll());
 89         } else {
 90             if (minHeap.isEmpty()) {
 91                 return;
 92             }
 93             
 94             // If the newly inserted value is larger than root of min-heap  
 95             // we need to pop the root of min-heap and insert it to max-heap.  
 96             // And pop root of max-heap and insert it to min-heap 
 97             if (minHeap.peek() < maxHeap.peek()) {
 98                 // exchange the top value in the minHeap and the maxHeap.
 99                 minHeap.offer(maxHeap.poll());
100                 maxHeap.offer(minHeap.poll());
101             }
102         }
103     }
104 
105     /*
106      * If maxHeap and minHeap are of different sizes, 
107      * then maxHeap must have one extra element.
108      */
109     public static double getMedian() {
110         if (maxHeap.isEmpty()) {
111             return -1;
112         }
113         
114         if (maxHeap.size() > minHeap.size()) {
115             return maxHeap.peek();
116         } else {
117             return (double)(maxHeap.peek() + minHeap.peek()) / 2;
118         }
119     }
120 }
View Code

GITHUB: https://github.com/yuzhangcmu/08722_DataStructures/blob/master/08722_LAB7/src/FindMedian_20150122.java

 

ref: http://blog.csdn.net/fightforyourdream/article/details/12748781

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。