I have a stream of integers, as well as an int k, given by the user. At the end of the program I must print the k highest numbers. I am only allowed to use a priority queue with a capacity of k.
My problem is that when the queue reaches full capacity, the next integer read must replace the lowest in the queue.
How can I keep the queue sorted after insertion, so that I know which int to replace in the next iteration, with O(logn) complexity? I use a swim method (presented bellow), but ,while it will place the new int at the right level, it doesn't keep the queue entirely sorted.
Here's the swim method:
private void swim(int i){
while (i > 1) { //if i root (i==1) return
int p = i/2; //find parent
int result = cmp.compare(heap[i], heap[p]); //compare parent with child
if (result == 1) return; //if child <= parent return
swap(i, p); //else swap and i=p
i = p;
}
}
To make myself more clear here's an example for k = 3.
1: A = 42 / B = null / C = null
2: A = 69 / B= 42 / C = null (69 swims upwards)
3: A = 69 / B= 42 / C = 32
4: A = 69 / B= 42 / C = 32 (no change)
5: A = 104 / B= 42 / C = 69 (104 is inserted replacing 32, then swims upwards)
6: A = 104 / B= 42 / C = 93 (93 is inserted replacing 69, remains there)
First of all, you can't keep the PriorityQueue
in sorted order; it is similar, if not exactly same as a heap data structure.
PriorityQueue
just grantee the top element is the min OR max according to it is min OR max heap.
And also you are getting confused between 2 different problems Sorting elements and Finding K max/min elements .
If you want to Sort elements in a given list of N elements:
You can't get a better running time than O(N*log(N)) using a comparison based sort algorithm.
But, if your case is just Finding K min/max elements from a list of N elements:
You can achieve it in O(N*log(K)) time.
Please check this question once: Finding the first n largest elements in an array
Even your comments In step 5, 104 and 69 switch places
and so that after each iteration, the lowest element is at C
are not consistent. Because in step 5 the lowest value 42
is at B
.
Maybe you are looking for a solution similar to this one.
public class FixedCapacityPriorityQueue {
static class MyPriorityQueue extends PriorityQueue<Integer> {
private final int capacity;
public MyPriorityQueue(int capacity) {
super(capacity, Comparator.reverseOrder());
this.capacity = capacity;
}
@Override
public boolean add(Integer i) {
super.add(i);
if (size() > capacity) {
Integer lowest = Integer.MAX_VALUE;
for (Integer next : this) {
if (lowest.compareTo(next) > 0) {
lowest = next;
}
}
this.remove(lowest);
}
return true;
}
}
public static void main(String[] args) {
Integer[] stream = {42, 69, 32, 5, 104, 93};
for (int i = 0; i < stream.length; i++) {
PriorityQueue queue = new MyPriorityQueue(3);
System.out.print("added to queue : ");
for (int e = 0; e <= i; e++) {
System.out.printf("%d ", stream[e]);
queue.add(stream[e]);
}
System.out.println();
System.out.print("elements in queue: ");
while (queue.size() > 0) {
System.out.printf("%d ", queue.poll());
}
System.out.printf("%n%n");
}
}
}
output
added to queue : 42
elements in queue: 42
added to queue : 42 69
elements in queue: 69 42
added to queue : 42 69 32
elements in queue: 69 42 32
added to queue : 42 69 32 5
elements in queue: 69 42 32
added to queue : 42 69 32 5 104
elements in queue: 104 69 42
added to queue : 42 69 32 5 104 93
elements in queue: 104 93 69
You can arrange you data in binary tree and with a binary tree search find the min number its time you want to delete something. The complexity for binary tree search is O(log N) and the insert of an element it has also O(log N) complexity.
Now talking about your constraint on the queue with length k you can transform the binary tree and store it in an array with length k.
You can check this link If I store a binary tree in an array, how do I avoid the wasted space? to take an idea on how to implement your binary tree in an array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.