Closest Room solution and explanation
8 more videos on this problem
花花酱 LeetCode 1847. Closest Room - 刷题找工作 EP393Hua Hua · 23:55 · 3K views
Leetcode Biweekly Contest 51 | Closest Room | Seat Reservation Manager | LEETCODE | CODE EXPLAINERcode Explainer · 20:24 · 1K views
LeetCode 1847. Closest RoomHappy Coding · 24:08 · 1K views
1847. Closest Room (Leetcode Hard)Programming Live with Larry · 15:26 · 725 views
【每日一题】1847. Closest Room, 5/5/2021Huifeng Guan · 17:48 · 351 views
LeetCode 1847. Closest Room | Biweekly Contest 51宰相小甘罗 · 5:53 · 217 views
LeetCode 1847. Closest Room 中文 | Biweekly Contest 51宰相小甘罗 · 6:09 · 98 views
LeetCode Hard 1847 Closest Roomrobzingcod · 13:14 · 25 views
LeetCode 1847: Closest RoomAlitaCode · 35:29 · 6 views
The problem
There is a hotel with n rooms. The rooms are represented by a 2D integer array rooms where rooms[i] = [roomIdi, sizei] denotes that there is a room with room number roomIdi and size equal to sizei. Each roomIdi is guaranteed to be unique.
You are also given k queries in a 2D array queries where queries[j] = [preferredj, minSizej]. The answer to the jth query is the room number id of a room such that:
- The room has a size of at least
minSizej, and abs(id - preferredj)is minimized, whereabs(x)is the absolute value ofx.
If there is a tie in the absolute difference, then use the room with the smallest such id. If there is no such room, the answer is -1.
Return an array answer of length k where answer[j] contains the answer to the jth query.
Example 1:
Input: rooms = [[2,2],[1,2],[3,2]], queries = [[3,1],[3,3],[5,2]] Output: [3,-1,3] Explanation: The answers to the queries are as follows: Query = [3,1]: Room number 3 is the closest as abs(3 - 3) = 0, and its size of 2 is at least 1. The answer is 3. Query = [3,3]: There are no rooms with a size of at least 3, so the answer is -1. Query = [5,2]: Room number 3 is the closest as abs(3 - 5) = 2, and its size of 2 is at least 2. The answer is 3.
Example 2:
Input: rooms = [[1,4],[2,3],[3,5],[4,1],[5,2]], queries = [[2,3],[2,4],[2,5]] Output: [2,1,3] Explanation: The answers to the queries are as follows: Query = [2,3]: Room number 2 is the closest as abs(2 - 2) = 0, and its size of 3 is at least 3. The answer is 2. Query = [2,4]: Room numbers 1 and 3 both have sizes of at least 4. The answer is 1 since it is smaller. Query = [2,5]: Room number 3 is the only room with a size of at least 5. The answer is 3.
Constraints:
n == rooms.length1 <= n <= 105k == queries.length1 <= k <= 1041 <= roomIdi, preferredj <= 1071 <= sizei, minSizej <= 107
Approach overview
Problem Overview: You are given a list of rooms where each room has an id and size. For every query [preferredId, minSize], return the room whose size is at least minSize and whose ID is closest to preferredId. If two rooms are equally close, return the smaller ID. If none satisfy the size constraint, return -1.
Approach 1: Sorting and Two-pointer with Ordered Set (O((n + q) log n) time, O(n) space)
Sort rooms in descending order of size. Sort queries by minSize in descending order while keeping their original indices. Iterate through queries and gradually add valid rooms (whose size ≥ current query's minSize) into an ordered structure containing room IDs. This behaves like a two-pointer sweep: one pointer scans the sorted rooms while queries are processed from largest to smallest size requirement.
Use an ordered set (such as TreeSet or a balanced BST) to maintain room IDs. For each query, perform a floor and ceiling search around preferredId. Compare distances and choose the closest ID. Each insertion and lookup costs O(log n), so the overall complexity becomes O((n + q) log n) with O(n) extra space. This approach combines sorting with an ordered set to efficiently maintain candidate rooms.
Approach 2: Binary Search with Sorting (O((n + q) log n) time, O(n) space)
Start by sorting rooms by size in descending order and processing queries in the same order of decreasing minSize. Maintain a dynamically growing sorted list of valid room IDs. As you move through the rooms list, insert each qualifying room ID into this structure.
For every query, perform binary search on the sorted IDs to locate the insertion position of preferredId. The closest candidate must be either the element just before or just after that position. Compute the absolute difference for both candidates and pick the best match (prefer smaller ID on ties). Binary search keeps each query lookup at O(log n), while insertions also cost O(log n) depending on the container used.
Recommended for interviews: The sorting + ordered set sweep is the solution most interviewers expect. It demonstrates control over offline query processing, sorting strategies, and efficient nearest-neighbor search using balanced trees. A brute force scan would take O(nq) and fails at scale, but explaining it first shows you understand the constraints. The optimized solution shows strong command of array preprocessing and logarithmic search structures.
Approach 1: Sorting and Two-pointer Approach
This approach focuses on sorting the rooms by size in descending order. For each query, we track the potential valid rooms that satisfy the minimum size condition using a two-pointer strategy along with a set data structure to efficiently find and sort room IDs based on the required distance.
We iterate over each query, updating the list of valid rooms, then determine the closest room ID using the sorted set.
from sortedcontainers import SortedList
def closestRoom(rooms, queries):
# Sort rooms by size, descending
rooms.sort(key=lambda x: -x[1])
queries = [(p, s, i) for i, (p, s) in enumerate(queries)]
# Sort queries by minSize, descending
queries.sort(key=lambda x: -x[1])
# Result array
answer = [-1] * len(queries)
# SortedList for room IDs
ids = SortedList()
j = 0
# Iterate over each query
for preferred, minSize, index in queries:
# Add all rooms that meet the quota size
while j < len(rooms) and rooms[j][1] >= minSize:
ids.add(rooms[j][0])
j += 1
# Find the nearest id
if ids:
pos = ids.bisect_left(preferred)
candidates = []
if pos < len(ids): candidates.append(ids[pos])
if pos > 0: candidates.append(ids[pos - 1])
# Determine closest
if candidates:
answer[index] = min(candidates, key=lambda x: (abs(x - preferred), x))
return answerimport java.util.*;
class Solution {
public int[] closestRoom(int[][] rooms, int[][] queries) {
Arrays.sort(rooms, (a, b) -> b[1] - a[1]); // Sort rooms by size desc.
int qLen = queries.length;
int[] answer = new int[qLen];
int[][] queriesWithIndex = new int[qLen][3];
// Storing queries with original index
for (int i = 0; i < qLen; i++) {
queriesWithIndex[i][0] = queries[i][0];
queriesWithIndex[i][1] = queries[i][1];
queriesWithIndex[i][2] = i;
}
Arrays.sort(queriesWithIndex, (a, b) -> b[1] - a[1]); // Sort by minSize desc.
TreeSet<Integer> availableRooms = new TreeSet<>();
int j = 0;
for (int[] query : queriesWithIndex) {
int preferred = query[0], minSize = query[1], index = query[2];
while (j < rooms.length && rooms[j][1] >= minSize) {
availableRooms.add(rooms[j][0]);
j++;
}
Integer floor = availableRooms.floor(preferred);
Integer ceil = availableRooms.ceiling(preferred);
if (floor == null && ceil == null) {
answer[index] = -1;
} else if (floor == null) {
answer[index] = ceil;
} else if (ceil == null) {
answer[index] = floor;
} else {
answer[index] = (preferred - floor <= ceil - preferred) ? floor : ceil;
}
}
return answer;
}
}The solution sorts the rooms based on size in descending order and processes each query in a similar fashion. It uses a SortedList to maintain a sorted list of room IDs that meet the size criteria for the current query. For each query, it represents the current valid rooms as sorted IDs to easily find those closest to the preferred room ID.
Time Complexity: O((n + k) log n). Sorting the rooms and queries each takes O(n log n) and O(k log k), respectively. Each query involves operations on a SortedList which are O(log n) on average.
Space Complexity: O(n), for storing room IDs in a sorted set.
Approach 2: Binary Search with Sorting
This approach optimizes the search by employing binary search. First, the rooms are sorted based on size, and for each query, a binary search is conducted to filter eligible rooms that meet minSize. Subsequently, a linear scan finds the closest room ID.
#include <vector>
#include <algorithm>
#include <set>
#include <limits.h>
using namespace std;
class Solution {
public:
vector<int> closestRoom(vector<vector<int>>& rooms, vector<vector<int>>& queries) {
sort(rooms.begin(), rooms.end(), [](const vector<int>& a, const vector<int>& b) { return a[1] > b[1]; });
vector<pair<pair<int, int>, int>> indexedQueries;
for (int i = 0; i < queries.size(); ++i) {
indexedQueries.push_back({{queries[i][0], queries[i][1]}, i});
}
sort(indexedQueries.begin(), indexedQueries.end(), [](const auto& a, const auto& b) { return a.first.second > b.first.second; });
vector<int> result(queries.size(), -1);
set<int> activeRooms;
int j = 0;
for (const auto& query : indexedQueries) {
int preferred = query.first.first;
int minSize = query.first.second;
int idx = query.second;
while (j < rooms.size() && rooms[j][1] >= minSize) {
activeRooms.insert(rooms[j][0]);
++j;
}
if (activeRooms.empty()) continue;
auto it = activeRooms.lower_bound(preferred);
int closestRoom = INT_MAX;
if (it != activeRooms.end()) {
closestRoom = *it;
}
if (it != activeRooms.begin()) {
--it;
if (abs(*it - preferred) <= abs(closestRoom - preferred)) {
closestRoom = *it;
}
}
result[idx] = closestRoom;
}
return result;
}
};function closestRoom(rooms, queries) {
rooms.sort((a, b) => b[1] - a[1]);
queries = queries.map((q, i) => [...q, i]);
queries.sort((a, b) => b[1] - a[1]);
const answer = Array(queries.length).fill(-1);
const availableRooms = new Set();
let j = 0;
for (const [preferred, minSize, index] of queries) {
while (j < rooms.length && rooms[j][1] >= minSize) {
availableRooms.add(rooms[j][0]);
j++;
}
if (availableRooms.size > 0) {
let closestId = -1;
let minDistance = Infinity;
for (const id of availableRooms) {
const distance = Math.abs(id - preferred);
if (distance < minDistance || (distance === minDistance && id < closestId)) {
minDistance = distance;
closestId = id;
}
}
answer[index] = closestId;
}
}
return answer;
}This C++ implementation utilizes sorting for rooms and queries. Binary search with two-pointer navigation improves efficiency over a naive linear search. The use of a set keeps room IDs ordered, and lower_bound is used for proximity checks.
Time Complexity: O((n + k) log n), where sorting and binary search operations predominate.
Space Complexity: O(n) for storing the current valid room IDs.
Approach 3: Offline Query + Ordered Set + Binary Search
We notice that the order of queries does not affect the answer, and the problem involves the size relationship of room areas. Therefore, we can sort the queries in ascending order of minimum area, so that we can process each query from small to large. Also, we sort the rooms in ascending order of area.
Next, we create an ordered list and add all room numbers to the ordered list.
Then, we process each query from small to large. For each query, we first remove all rooms with an area less than or equal to the current query's minimum area from the ordered list. Then, in the remaining rooms, we use binary search to find the room number closest to the current query. If there is no such room, we return -1.
The time complexity is O(n times log n + k times log k), and the space complexity is O(n + k). Where n and k are the number of rooms and queries, respectively.
func closestRoom(rooms [][]int, queries [][]int) []int {
n, k := len(rooms), len(queries)
sort.Slice(rooms, func(i, j int) bool { return rooms[i][1] < rooms[j][1] })
idx := make([]int, k)
ans := make([]int, k)
for i := range idx {
idx[i] = i
ans[i] = -1
}
sort.Slice(idx, func(i, j int) bool { return queries[idx[i]][1] < queries[idx[j]][1] })
rbt := redblacktree.NewWithIntComparator()
merge := func(rbt *redblacktree.Tree, key, value int) {
if v, ok := rbt.Get(key); ok {
nxt := v.(int) + value
if nxt == 0 {
rbt.Remove(key)
} else {
rbt.Put(key, nxt)
}
} else {
rbt.Put(key, value)
}
}
for _, room := range rooms {
merge(rbt, room[0], 1)
}
i := 0
for _, j := range idx {
prefer, minSize := queries[j][0], queries[j][1]
for i < n && rooms[i][1] < minSize {
merge(rbt, rooms[i][0], -1)
i++
}
if i == n {
break
}
c, _ := rbt.Ceiling(prefer)
f, _ := rbt.Floor(prefer)
if c != nil {
ans[j] = c.Key.(int)
}
if f != nil && (ans[j] == -1 || ans[j]-prefer >= prefer-f.Key.(int)) {
ans[j] = f.Key.(int)
}
}
return ans
}Complexity comparison
| Approach | Complexity |
|---|---|
| Sorting and Two-pointer Approach | Time Complexity: O((n + k) log n). Sorting the rooms and queries each takes O(n log n) and O(k log k), respectively. Each query involves operations on a SortedList which are O(log n) on average. |
| Binary Search with Sorting | Time Complexity: O((n + k) log n), where sorting and binary search operations predominate. |
| Offline Query + Ordered Set + Binary Search | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Scan | O(nq) | O(1) | Small input sizes or when optimizing is unnecessary |
| Sorting + Ordered Set (Two-pointer sweep) | O((n + q) log n) | O(n) | Best general solution for large inputs and interview settings |
| Binary Search on Sorted IDs | O((n + q) log n) | O(n) | When using languages with built-in sorted containers or bisect utilities |
Frequently asked questions
Is Closest Room easy or hard?
Closest Room is classified as a Hard problem on LeetCode. The challenge comes from combining multiple techniques: offline query sorting, maintaining dynamic candidate sets, and performing nearest-ID searches efficiently.
Closest Room Python/Java solution
Python implementations typically combine sorting with the bisect module or the SortedList structure from sortedcontainers. Java solutions often use TreeSet for floor and ceiling queries. Both implementations achieve O((n + q) log n) time complexity.
How to solve Closest Room in O(n)?
A strict O(n) solution is not practical because queries require nearest-ID lookups among dynamically inserted rooms. Efficient solutions rely on balanced search structures or binary search over sorted IDs, which introduces a log n factor. The best achievable complexity in practice is O((n + q) log n).
What is the best approach for Closest Room?
The optimal solution sorts rooms by size and processes queries offline in descending order of minimum size. Valid room IDs are inserted into an ordered set, and each query finds the nearest ID using floor and ceiling lookups. This approach runs in O((n + q) log n) time and O(n) space, which scales well for large inputs.
Is Closest Room asked at Google/Amazon/Meta?
Problems involving offline query processing, ordered sets, and nearest-value search appear frequently in interviews at companies like Google, Amazon, and Meta. Closest Room specifically tests sorting strategies, balanced tree operations, and binary search reasoning under constraints.
What data structure is used in Closest Room?
The core data structure is an ordered set or balanced binary search tree storing room IDs. It supports fast insertion and nearest-value queries using floor and ceiling operations. Some implementations simulate this behavior using a sorted list with binary search.
What is the time complexity of Closest Room?
The optimal algorithm runs in O((n + q) log n) time. Sorting rooms and queries costs O(n log n + q log q), while each insertion and nearest-ID lookup in the ordered set costs O(log n). Space complexity is O(n) to store the active room IDs.
