Una implementación de trabajo en java, usando 2 montones, O (n log n). En cualquier momento, mantengo los dos montones equilibrados en tamaño (es decir, difieren a lo sumo en 1, si ingresamos n elementos tales que n% 2 == 1). Obtener la mediana es O (1). Agregar un nuevo elemento es O (log n).
public class MedianOfStream {
private int count;
private PriorityQueue<Integer> highs, lows;
public MedianOfStream() {
highs = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1) {
return arg0.compareTo(arg1);
}
});
lows = new PriorityQueue<Integer>(11, new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1) {
return arg1.compareTo(arg0);
}
});
}
private int getMedian() {
if (count == 0)
return 0;
if (lows.size() == highs.size()) {
return (lows.peek() + highs.peek())/2;
} else if (lows.size() < highs.size()) {
return highs.peek();
}
return lows.peek();
}
private void swap(){
int h = highs.poll();
int l = lows.poll();
highs.add(l);
lows.add(h);
}
public int updateMedian(int n) {
count++;
if (count == 1)
lows.add(n);
else if (count==2) {
highs.add(n);
if(highs.peek()<lows.peek()) {
swap(); // O(log n)
}
}
else {
if (n > highs.peek()) {
lows.add(highs.poll()); // O(log n)
highs.add(n); // O(log n)
} else {
highs.add(lows.poll()); // O(log n)
lows.add(n); // O(log n)
}
if(highs.peek()<lows.peek()) {
swap(); // O(log n)
}
}
// if we added an even # of items,
// the heaps must be exactly the same size,
// otherwise we tolerate a 1-off difference
if (Math.abs(lows.size() - highs.size()) > (count % 2)) {
if (lows.size() < highs.size()) {
lows.add(highs.poll()); // O(log n)
} else {
highs.add(lows.poll()); // O(log n)
}
}
return getMedian(); // O(1)
}
}
Lo que se ha adivinado? – Gumbo
Supongo que la verdadera pregunta es poder determinar la mediana rápidamente incluso después de muchas inserciones y de alguna manera se perdió en la traducción. Francamente, esto parece una pregunta de tarea disfrazada como una pregunta de entrevista. –
@Moron: No estoy de acuerdo con la evaluación de la tarea. Es muy fácil simplemente copiar la declaración de la tarea y no introducir problemas de "pérdida en la traducción". Esto huele más como una pregunta de entrevista que se perdió en la traducción. – jason