CSES Solutions - Room Allocation
Last Updated :
24 Feb, 2025
There is a large hotel, and N customers will arrive soon. Each customer wants to have a single room. You know each customer's arrival and departure day as timings[][] such that timings[i][0] is the arrival time and timings[i][1] is the departure time of ith person. Two customers can stay in the same room if the departure day of the first customer is earlier than the arrival day of the second customer.
What is the minimum number of rooms that are needed to accommodate all customers? And how can the rooms be allocated?
Note: If k is the minimum number of rooms, then the rooms are numbered from 1 to k. Return any valid solution.
Examples:
Input: N = 3, timings[][] = {{1, 2}, {2, 4}, {4, 4}}
Output:
2
1 2 1
Explanation:
- The first person arrives at time = 1 and gets room 1.
- The second person arrives at time = 2. Since room 1 is already occupied by the first person, second person will get room 2.
- The third person arrives at time = 4. Since the first person has already left, third person will get room 1.
Input: N = 4, timings[][] = {{6, 6}, {5, 5}, {6, 6}, {5, 10}}
Output:
3
1 1 3 2
Explanation:
- The second person arrivesat time = 5 and gets room 1.
- The fourth person arrives at time = 5. Since room 1 is already occupied by second person, fourth person will get room 2.
- The first person arrives at time = 6. Since the second person has already left, the first person will get room 1.
- The third person arrives at time = 6. Since room1 is already occupied by first person and room2 is already occupied by fourth person, the third person will get room 3.
Approach: To solve the problem, follow the below idea:
The problem can be solved using Greedy Approach. Sort all the customers in increasing order of their arrival times. This way, a customer who arrives earlier gets a room before a customer who arrives later. Also, keep track of the departure times of the customers we have already given rooms to, using a Priority Queue (Min Heap).
For each new customer, we check if any of the current customers will leave before the new customer arrives by comparing the arrival time with the top of the priority queue.
- If any of the current customers will leave, then the new customer can take the room of the customer who is leaving. So, we update the departure time in our system with the departure time of the new customer.
- If no customer leaves, that means all the rooms are currently occupied and will still be occupied when the new customer arrives. So, we need to provide a new room for this customer and add their departure time to our system.
The minimum number of rooms needed is the largest number of rooms we find ourselves using at any point in this process.
C++
// C++ program to implement
// room allocation problem.
#include <bits/stdc++.h>
using namespace std;
// function to find the minimum number of rooms and the
// rooms allocated to each customer
void minimumRooms(vector<vector<int> >& timings) {
int n = timings.size();
// vector to store the {arrival, departure, index} of
// all customers
vector<vector<int> > vec(n, vector<int>(3));
for (int i = 0; i < n; i++) {
vec[i][0] = timings[i][0];
vec[i][1] = timings[i][1];
vec[i][2] = i;
}
// Sort the vector according to the arrival time of
// customers
sort(vec.begin(), vec.end());
// Min heap to store {departure, room number} to fetch
// the room which gets vacant the earliest
priority_queue<pair<int, int>, vector<pair<int, int> >,
greater<pair<int, int> > >
occupiedRooms;
// Variable to store the total number of rooms needed
int roomCnt = 0;
// vector to store the room alloted to each customer
vector<int> ans(n);
for (int i = 0; i < n; i++) {
int arrivalTime = vec[i][0];
int departureTime = vec[i][1];
int idx = vec[i][2];
// Check if there are no rooms available or all the
// rooms are occupied
if (occupiedRooms.empty()
|| occupiedRooms.top().first >= arrivalTime) {
// If there are no rooms or all the rooms are
// occupied, then increment the total number of
// rooms needed and allocate the room to the
// current customer
roomCnt += 1;
occupiedRooms.push({ departureTime, roomCnt });
ans[idx] = roomCnt;
}
else {
// If there is a vacant room, then assign that
// vacant room to the current customer
int vacantRoom = occupiedRooms.top().second;
occupiedRooms.pop();
occupiedRooms.push(
{ departureTime, vacantRoom });
ans[idx] = vacantRoom;
}
}
// Print the total rooms needed along with the room
// allocated to each customer
cout << roomCnt << "\n";
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
cout << endl;
}
int main() {
vector<vector<int>> timings = {{1, 2}, {2, 4}, {4, 4}};
minimumRooms(timings);
return 0;
}
Java
// Java program to implement
// room allocation problem.
import java.util.*;
class GfG {
// function to find the minimum number of rooms and the
// rooms allocated to each customer
static void minimumRooms(int[][] timings) {
int n = timings.length;
// array to store the {arrival, departure, index} of
// all customers
int[][] vec = new int[n][3];
for (int i = 0; i < n; i++) {
vec[i][0] = timings[i][0];
vec[i][1] = timings[i][1];
vec[i][2] = i;
}
// Sort the array according to the arrival time of
// customers
Arrays.sort(vec, Comparator.comparingInt(a -> a[0]));
// Min heap to store {departure, room number} to fetch
// the room which gets vacant the earliest
PriorityQueue<int[]> occupiedRooms =
new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
// Variable to store the total number of rooms needed
int roomCnt = 0;
// array to store the room allotted to each customer
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
int arrivalTime = vec[i][0];
int departureTime = vec[i][1];
int idx = vec[i][2];
// Check if there are no rooms available or all the
// rooms are occupied
if (occupiedRooms.isEmpty() ||
occupiedRooms.peek()[0] >= arrivalTime) {
// If there are no rooms or all the rooms are
// occupied, then increment the total number of
// rooms needed and allocate the room to the
// current customer
roomCnt += 1;
occupiedRooms.add(new int[]{departureTime, roomCnt});
ans[idx] = roomCnt;
} else {
// If there is a vacant room, then assign that
// vacant room to the current customer
int vacantRoom = occupiedRooms.poll()[1];
occupiedRooms.add(new int[]{departureTime, vacantRoom});
ans[idx] = vacantRoom;
}
}
// Print the total rooms needed along with the room
// allocated to each customer
System.out.println(roomCnt);
for (int i = 0; i < ans.length; i++)
System.out.print(ans[i] + " ");
System.out.println();
}
public static void main(String[] args) {
int[][] timings = {{1, 2}, {2, 4}, {4, 4}};
minimumRooms(timings);
}
}
Python
# Python program to implement
# room allocation problem.
import heapq
# function to find the minimum number of rooms and the
# rooms allocated to each customer
def minimumRooms(timings):
n = len(timings)
# list to store the {arrival, departure, index} of
# all customers
vec = [[timings[i][0], timings[i][1], i] for i in range(n)]
# Sort the list according to the arrival time of
# customers
vec.sort()
# Min heap to store {departure, room number} to fetch
# the room which gets vacant the earliest
occupiedRooms = []
# Variable to store the total number of rooms needed
roomCnt = 0
# list to store the room allotted to each customer
ans = [0] * n
for i in range(n):
arrivalTime, departureTime, idx = vec[i]
# Check if there are no rooms available or all the
# rooms are occupied
if not occupiedRooms or occupiedRooms[0][0] >= arrivalTime:
# If there are no rooms or all the rooms are
# occupied, then increment the total number of
# rooms needed and allocate the room to the
# current customer
roomCnt += 1
heapq.heappush(occupiedRooms, (departureTime, roomCnt))
ans[idx] = roomCnt
else:
# If there is a vacant room, then assign that
# vacant room to the current customer
vacantRoom = heapq.heappop(occupiedRooms)[1]
heapq.heappush(occupiedRooms, (departureTime, vacantRoom))
ans[idx] = vacantRoom
# Print the total rooms needed along with the room
# allocated to each customer
print(roomCnt)
print(*ans)
if __name__ == "__main__":
timings = [[1, 2], [2, 4], [4, 4]]
minimumRooms(timings)
C#
// C# program to implement
// room allocation problem.
using System;
using System.Collections.Generic;
class Pair {
public int first, second;
public Pair(int first, int second) {
this.first = first;
this.second = second;
}
}
class intComparer : IComparer<Pair> {
public int Compare(Pair a, Pair b) {
if (a.first > b.first)
return 1;
else if (a.first < b.first)
return -1;
return 0;
}
}
class GfG {
// function to find the minimum number of rooms and the
// rooms allocated to each customer
static void minimumRooms(int[][] timings) {
int n = timings.Length;
// array to store the {arrival, departure, index} of
// all customers
int[][] vec = new int[n][];
for (int i = 0; i < n; i++) {
vec[i] = new int[] { timings[i][0], timings[i][1], i };
}
// Sort the array according to the arrival time of
// customers
Array.Sort(vec, (a, b) => a[0].CompareTo(b[0]));
// Min heap to store {departure, room number} to fetch
// the room which gets vacant the earliest
PriorityQueue<Pair> occupiedRooms = new PriorityQueue<Pair>(new intComparer());
// Variable to store the total number of rooms needed
int roomCnt = 0;
// array to store the room allotted to each customer
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
int arrivalTime = vec[i][0];
int departureTime = vec[i][1];
int idx = vec[i][2];
// Check if there are no rooms available or all the
// rooms are occupied
if (occupiedRooms.Count == 0 || occupiedRooms.Peek().first >= arrivalTime) {
// If there are no rooms or all the rooms are
// occupied, then increment the total number of
// rooms needed and allocate the room to the
// current customer
roomCnt += 1;
occupiedRooms.Enqueue(new Pair(departureTime, roomCnt));
ans[idx] = roomCnt;
} else {
// If there is a vacant room, then assign that
// vacant room to the current customer
int vacantRoom = occupiedRooms.Dequeue().second;
occupiedRooms.Enqueue(new Pair(departureTime, vacantRoom));
ans[idx] = vacantRoom;
}
}
// Print the total rooms needed along with the room
// allocated to each customer
Console.WriteLine(roomCnt);
Console.WriteLine(string.Join(" ", ans));
}
static void Main() {
int[][] timings = { new int[] { 1, 2 },
new int[] { 2, 4 }, new int[] { 4, 4 } };
minimumRooms(timings);
}
}
class PriorityQueue<T> {
private List<T> heap;
private IComparer<T> comparer;
public PriorityQueue(IComparer<T> comparer = null) {
this.heap = new List<T>();
this.comparer = comparer ?? Comparer<T>.Default;
}
public int Count => heap.Count;
// Enqueue operation
public void Enqueue(T item) {
heap.Add(item);
int i = heap.Count - 1;
while (i > 0) {
int parent = (i - 1) / 2;
if (comparer.Compare(heap[parent], heap[i]) <= 0)
break;
Swap(parent, i);
i = parent;
}
}
public T Peek() {
return heap[0];
}
// Dequeue operation
public T Dequeue() {
if (heap.Count == 0)
throw new InvalidOperationException("Priority queue is empty.");
T result = heap[0];
int last = heap.Count - 1;
heap[0] = heap[last];
heap.RemoveAt(last);
last--;
int i = 0;
while (true) {
int left = 2 * i + 1;
if (left > last)
break;
int right = left + 1;
int minChild = left;
if (right <= last && comparer.Compare(heap[right], heap[left]) < 0)
minChild = right;
if (comparer.Compare(heap[i], heap[minChild]) <= 0)
break;
Swap(i, minChild);
i = minChild;
}
return result;
}
// Swap two elements in the heap
private void Swap(int i, int j) {
T temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}
JavaScript
// Function to find the minimum number of rooms and the
// rooms allocated to each customer
function solve(timings) {
// Sort the timings array based on arrival times
timings.sort((a, b) => a[0] - b[0]);
// Min heap to store {departure, room number} to fetch
// the room which gets vacant the earliest
let occupiedRooms = new MinHeap();
// Variable to store the total number of rooms needed
let roomCnt = 0;
// Array to store the room allocated to each customer
let ans = [];
for (let i = 0; i < timings.length; i++) {
let arrivalTime = timings[i][0];
let departureTime = timings[i][1];
// Check if there are no rooms available or all the
// rooms are occupied
if (occupiedRooms.isEmpty() || occupiedRooms.top().departure >= arrivalTime) {
// If there are no rooms or all the rooms are
// occupied, then increment the total number of
// rooms needed and allocate the room to the
// current customer
roomCnt++;
occupiedRooms.push({ departure: departureTime, room: roomCnt });
ans.push(roomCnt);
} else {
// If there is a vacant room, then assign that
// vacant room to the current customer
let vacantRoom = occupiedRooms.pop().room;
occupiedRooms.push({ departure: departureTime, room: vacantRoom });
ans.push(vacantRoom);
}
}
// Print the total rooms needed along with the room
// allocated to each customer
console.log(roomCnt);
console.log(ans.join(" "));
}
// Priority queue implementation for the min heap
class MinHeap {
constructor() {
this.heap = [];
}
push(value) {
this.heap.push(value);
this.heapifyUp();
}
pop() {
if (this.isEmpty()) return null;
this.swap(0, this.heap.length - 1);
const poppedValue = this.heap.pop();
this.heapifyDown();
return poppedValue;
}
top() {
return this.heap[0];
}
isEmpty() {
return this.heap.length === 0;
}
heapifyUp() {
let currentIdx = this.heap.length - 1;
let parentIdx = Math.floor((currentIdx - 1) / 2);
while (currentIdx > 0 && this.heap[currentIdx].departure < this.heap[parentIdx].departure) {
this.swap(currentIdx, parentIdx);
currentIdx = parentIdx;
parentIdx = Math.floor((currentIdx - 1) / 2);
}
}
heapifyDown() {
let currentIdx = 0;
let leftChildIdx = 2 * currentIdx + 1;
while (leftChildIdx < this.heap.length) {
let rightChildIdx = 2 * currentIdx + 2 < this.heap.length ? 2 * currentIdx + 2 : -1;
let idxToSwap;
if (rightChildIdx !== -1 && this.heap[rightChildIdx].departure < this.heap[leftChildIdx].departure) {
idxToSwap = rightChildIdx;
} else {
idxToSwap = leftChildIdx;
}
if (this.heap[idxToSwap].departure < this.heap[currentIdx].departure) {
this.swap(currentIdx, idxToSwap);
currentIdx = idxToSwap;
leftChildIdx = 2 * currentIdx + 1;
} else {
break;
}
}
}
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
}
let timings = [
[1, 2],
[2, 4],
[4, 4]
];
solve(timings);
Time Complexity: O(n * log n), where n is the number of customers.
Auxiliary Space: O(n)
Similar Reads
CSES Solutions - Book Shop
You are in a book shop which sells N different books. You know the price and number of pages of each book. You have decided that the total price of your purchases will be at most X. What is the maximum number of pages you can buy? You can buy each book at most once. Examples: Input: N = 4, X = 10, p
7 min read
CSES Solutions - Apartments
There are N applicants and M free apartments. Your task is to distribute the apartments so that as many applicants as possible will get an apartment. Each applicant has a desired apartment size given in array A[] of size N and each apartment has a size given in array B[] of size M. An applicant will
9 min read
Task Allocation to Game Slots
Given an array of n tasks, each represented by two arrays: start_time and duration. The start_time array represents the start time of each task, and the duration array represents the duration of each task. Your goal is to design an allocation strategy for these tasks to maximize their chances of bei
10 min read
Post Box Allocation
Given with array of apartments where apartments[i] is the location of the ith apartment along a street and an integer p postboxes in the street. Return the minimum total distance between each apartment and its nearest postbox. Examples: Input : apartments = [ 1 , 4 , 8 , 10 , 20 ] , p = 3Output : 5E
11 min read
Maximum Cinema Seat Allocation
A cinema has n rows of seats, numbered from 1 to n and there are ten seats in each row, labelled from 1 to 10 as shown in the figure above. Given the array reservedSeats containing the numbers of seats already reserved, for example, reservedSeats[i] = [3,8] means the seat located in row 3 and labell
8 min read
CSES Solutions - Concert Tickets
There are N concert tickets available, each with a certain price given as array tickets[]. Then, M customers arrive, one after another. Each customer announces the maximum price they are willing to pay for a ticket given as array customer[], and after this, they will get a ticket with the nearest po
7 min read
CSES Solutions - Factory Machines
A factory has N machines which can be used to make products. Your goal is to make a total of T products. For each machine, you know the number of seconds it needs to make a single product, given as array K[]. The machines can work simultaneously, and you can freely decide their schedule. What is the
9 min read
CSES Solutions - Ferris Wheel
There are N children who want to go to a Ferris wheel in the form of array arr[], and your task is to find a gondola for each child. Each gondola may have one or two children in it, and in addition, the total weight in a gondola may not exceed X. You know the weight of every child. What is the minim
6 min read
CSES Solutions - Restaurant Customers
You are given the arrival and leaving times of N customers in a restaurant as array customers[][], such that customer[i][0] is the arrival time and customer[i][1] is the leaving time. What was the maximum number of customers in the restaurant at any time? You may assume that all arrival and leaving
6 min read
CSES Solutions - Movie Festival II
In a movie festival, N movies will be shown. Syrjälä's movie club consists of K members, who will all be attending the festival. Given the starting and ending times of each movie. What is the maximum total number of movies the club members can watch entirely if they act optimally? Examples: Input: N
10 min read