🧠
Using Min-Heap (Priority Queue) to Track Platforms
💡 This approach uses a min-heap to track the earliest departure time among trains currently occupying platforms, allowing dynamic allocation of platforms.
Intuition
Sort trains by arrival time. For each train, if its arrival is after or equal to the earliest departure (top of min-heap), reuse that platform by popping from heap. Otherwise, allocate a new platform by pushing departure time. The heap size at any time is platforms needed.
Algorithm
- Create a list of pairs (arrival, departure) and sort by arrival time.
- Initialize a min-heap to store departure times.
- Iterate over sorted trains:
- If heap is not empty and current arrival >= earliest departure (heap top), pop from heap (platform freed).
- Push current train's departure time into heap (platform allocated).
- Track max heap size during iteration as minimum platforms needed.
- Return max heap size.
💡 The heap dynamically tracks platform availability, making it easy to allocate or free platforms in O(log n) time per train.
import heapq
def min_platforms_min_heap(arrivals, departures):
trains = sorted(zip(arrivals, departures), key=lambda x: x[0])
heap = []
max_platforms = 0
for arrival, departure in trains:
while heap and heap[0] <= arrival:
heapq.heappop(heap)
heapq.heappush(heap, departure)
max_platforms = max(max_platforms, len(heap))
return max_platforms
# Driver code
if __name__ == '__main__':
arrivals = [900, 940, 950, 1100, 1500, 1800]
departures = [910, 1200, 1120, 1130, 1900, 2000]
print(min_platforms_min_heap(arrivals, departures))
Line Notes
trains = sorted(zip(arrivals, departures), key=lambda x: x[0])Pair and sort trains by arrival time for chronological processing.
heap = []Initialize min-heap to track earliest departure times.
while heap and heap[0] <= arrival:Remove all trains that have departed before or exactly at current arrival, freeing platforms.
heapq.heappop(heap)Pop earliest departure time from heap to free platform.
heapq.heappush(heap, departure)Add current train's departure time to heap, allocating platform.
max_platforms = max(max_platforms, len(heap))Track maximum platforms needed as heap size.
import java.util.*;
public class MinPlatformsMinHeap {
public static int minPlatforms(int[] arrivals, int[] departures) {
int n = arrivals.length;
int[][] trains = new int[n][2];
for (int i = 0; i < n; i++) {
trains[i][0] = arrivals[i];
trains[i][1] = departures[i];
}
Arrays.sort(trains, Comparator.comparingInt(a -> a[0]));
PriorityQueue<Integer> heap = new PriorityQueue<>();
int maxPlatforms = 0;
for (int[] train : trains) {
while (!heap.isEmpty() && heap.peek() <= train[0]) {
heap.poll();
}
heap.offer(train[1]);
maxPlatforms = Math.max(maxPlatforms, heap.size());
}
return maxPlatforms;
}
public static void main(String[] args) {
int[] arrivals = {900, 940, 950, 1100, 1500, 1800};
int[] departures = {910, 1200, 1120, 1130, 1900, 2000};
System.out.println(minPlatforms(arrivals, departures));
}
}
Line Notes
int[][] trains = new int[n][2];Create array of train arrival and departure pairs.
Arrays.sort(trains, Comparator.comparingInt(a -> a[0]));Sort trains by arrival time.
PriorityQueue<Integer> heap = new PriorityQueue<>();Min-heap to track earliest departure times.
while (!heap.isEmpty() && heap.peek() <= train[0]) {Remove trains that have departed before or exactly at current arrival.
heap.poll();Pop earliest departure to free platform.
heap.offer(train[1]);Add current train's departure time to heap.
maxPlatforms = Math.max(maxPlatforms, heap.size());Track max platforms needed.
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
int minPlatformsMinHeap(vector<int>& arrivals, vector<int>& departures) {
int n = arrivals.size();
vector<pair<int,int>> trains(n);
for (int i = 0; i < n; i++) {
trains[i] = {arrivals[i], departures[i]};
}
sort(trains.begin(), trains.end());
priority_queue<int, vector<int>, greater<int>> minHeap;
int maxPlatforms = 0;
for (auto& train : trains) {
while (!minHeap.empty() && minHeap.top() <= train.first) {
minHeap.pop();
}
minHeap.push(train.second);
maxPlatforms = max(maxPlatforms, (int)minHeap.size());
}
return maxPlatforms;
}
int main() {
vector<int> arrivals = {900, 940, 950, 1100, 1500, 1800};
vector<int> departures = {910, 1200, 1120, 1130, 1900, 2000};
cout << minPlatformsMinHeap(arrivals, departures) << endl;
return 0;
}
Line Notes
vector<pair<int,int>> trains(n);Pair arrival and departure times for sorting.
sort(trains.begin(), trains.end());Sort trains by arrival time.
priority_queue<int, vector<int>, greater<int>> minHeap;Min-heap to track earliest departure times.
while (!minHeap.empty() && minHeap.top() <= train.first) {Remove trains that have departed before or exactly at current arrival.
minHeap.pop();Pop earliest departure to free platform.
minHeap.push(train.second);Add current train's departure time to heap.
maxPlatforms = max(maxPlatforms, (int)minHeap.size());Track max platforms needed.
class MinHeap {
constructor() {
this.heap = [];
}
parent(i) { return Math.floor((i - 1) / 2); }
left(i) { return 2 * i + 1; }
right(i) { return 2 * i + 2; }
swap(i, j) { [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]]; }
push(val) {
this.heap.push(val);
let i = this.heap.length - 1;
while (i > 0 && this.heap[this.parent(i)] > this.heap[i]) {
this.swap(i, this.parent(i));
i = this.parent(i);
}
}
pop() {
if (this.heap.length === 0) return null;
const root = this.heap[0];
const end = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = end;
this.heapify(0);
}
return root;
}
heapify(i) {
let smallest = i;
const left = this.left(i);
const right = this.right(i);
if (left < this.heap.length && this.heap[left] < this.heap[smallest]) smallest = left;
if (right < this.heap.length && this.heap[right] < this.heap[smallest]) smallest = right;
if (smallest !== i) {
this.swap(i, smallest);
this.heapify(smallest);
}
}
peek() {
return this.heap.length > 0 ? this.heap[0] : null;
}
size() {
return this.heap.length;
}
}
function minPlatformsMinHeap(arrivals, departures) {
const trains = arrivals.map((a, i) => [a, departures[i]]).sort((a, b) => a[0] - b[0]);
const heap = new MinHeap();
let maxPlatforms = 0;
for (const [arrival, departure] of trains) {
while (heap.size() > 0 && heap.peek() <= arrival) {
heap.pop();
}
heap.push(departure);
maxPlatforms = Math.max(maxPlatforms, heap.size());
}
return maxPlatforms;
}
// Test
const arrivals = [900, 940, 950, 1100, 1500, 1800];
const departures = [910, 1200, 1120, 1130, 1900, 2000];
console.log(minPlatformsMinHeap(arrivals, departures));
Line Notes
const trains = arrivals.map((a, i) => [a, departures[i]]).sort((a, b) => a[0] - b[0]);Pair and sort trains by arrival time.
const heap = new MinHeap();Initialize min-heap to track earliest departure times.
while (heap.size() > 0 && heap.peek() <= arrival) {Remove trains that have departed before or exactly at current arrival.
heap.pop();Pop earliest departure to free platform.
heap.push(departure);Add current train's departure time to heap.
maxPlatforms = Math.max(maxPlatforms, heap.size());Track maximum platforms needed.
Sorting takes O(n log n), and each train is pushed and popped from heap at most once, each operation O(log n).
💡 For n=100000, this approach is efficient and uses extra space for the heap but is practical.
Interview Verdict: Accepted
This approach is optimal and useful when you want to track platforms dynamically or extend to more complex constraints.