Priority Queue
Data Structure · Core
Step through it: Top K Elements pattern
Step 1 of 6
Goal: find the 3 biggest numbers. Sorting everything works but does more than needed. Instead keep a small club of the best 3 so far and always know its weakest member, the first to be kicked out. (A min-heap gives you the weakest in one step.)
Step 2 of 6
Take in 5, 1 and 9. The club is full: 1, 5, 9. The weakest member is 1.
Step 3 of 6
Next is 3. It beats the weakest (1), so 1 leaves and 3 joins: 3, 5, 9.
Step 4 of 6
7 beats the new weakest (3). Club: 5, 7, 9.
Step 5 of 6
2 is smaller than the weakest (5), so ignore it. The club is the answer: 5, 7, 9. Each number costs one quick heap update, about n log k steps in all. This is the Top K pattern.
Step 6 of 6
Your turn.
In computer science, a priority queue is an abstract data type which is like a regular queue or stack data structure, but where additionally each element has a "priority" associated with it. In a priority queue, an element with high priority is served before an element with low priority. If two elements have the same priority, they are served according to their order in the queue.
While priority queues are often implemented with heaps, they are conceptually distinct from heaps. A priority queue is an abstract concept like "a list" or "a map"; just as a list can be implemented with a linked list or an array, a priority queue can be implemented with a heap or a variety of other methods such as an unordered array.
Code
import MinHeap from '../heap/MinHeap';
import Comparator from '../../utils/comparator/Comparator';
// It is the same as min heap except that when comparing two elements
// we take into account its priority instead of the element's value.
export default class PriorityQueue extends MinHeap {
constructor() {
// Call MinHip constructor first.
super();
// Setup priorities map.
this.priorities = new Map();
// Use custom comparator for heap elements that will take element priority
// instead of element value into account.
this.compare = new Comparator(this.comparePriority.bind(this));
}
/**
* Add item to the priority queue.
* @param {*} item - item we're going to add to the queue.
* @param {number} [priority] - items priority.
* @return {PriorityQueue}
*/
add(item, priority = 0) {
this.priorities.set(item, priority);
super.add(item);
return this;
}
/**
* Remove item from priority queue.
* @param {*} item - item we're going to remove.
* @param {Comparator} [customFindingComparator] - custom function for finding the item to remove
* @return {PriorityQueue}
*/
remove(item, customFindingComparator) {
super.remove(item, customFindingComparator);
this.priorities.delete(item);
return this;
}
/**
* Change priority of the item in a queue.
* @param {*} item - item we're going to re-prioritize.
* @param {number} priority - new item's priority.
* @return {PriorityQueue}
*/
changePriority(item, priority) {
this.remove(item, new Comparator(this.compareValue));
this.add(item, priority);
return this;
}
/**
* Find item by ite value.
* @param {*} item
* @return {Number[]}
*/
findByValue(item) {
return this.find(item, new Comparator(this.compareValue));
}
/**
* Check if item already exists in a queue.
* @param {*} item
* @return {boolean}
*/
hasValue(item) {
return this.findByValue(item).length > 0;
}
/**
* Compares priorities of two items.
* @param {*} a
* @param {*} b
* @return {number}
*/
comparePriority(a, b) {
if (this.priorities.get(a) === this.priorities.get(b)) {
return 0;
}
return this.priorities.get(a) < this.priorities.get(b) ? -1 : 1;
}
/**
* Compares values of two items.
* @param {*} a
* @param {*} b
* @return {number}
*/
compareValue(a, b) {
if (a === b) {
return 0;
}
return a < b ? -1 : 1;
}
}References
Practice
Top K Elements
- Kth Largest Element in a StreamEasy
- Last Stone WeightEasy
- Kth Largest Element in an ArrayMedium
- Top K Frequent ElementsMedium
- Top K Frequent WordsMedium
- K Closest Points to OriginMedium
- Sort Characters By FrequencyMedium
- Task SchedulerMedium
- Reorganize StringMedium
- Find K Pairs with Smallest SumsMedium
- Kth Smallest Element in a Sorted MatrixMedium
- Meeting Rooms IIMedium
- Furthest Building You Can ReachMedium
- Merge k Sorted ListsHard
- Find Median from Data StreamHard
- Smallest Range Covering Elements from K ListsHard
Spotted a mistake or something unclear? Report it on GitHub.