Talentd
FleetCode
Make and follow sheets.Sign in

Closest Room solution and explanation

HardArrayBinary SearchOrdered SetSorting8 min read41.9% acceptanceUpdated 9 Apr 2026
花花酱 LeetCode 1847. Closest Room - 刷题找工作 EP393Hua Hua · 23:55 · 3K viewsWatch on YouTube
8 more videos on this problem
  1. 花花酱 LeetCode 1847. Closest Room - 刷题找工作 EP393Hua Hua · 23:55 · 3K views
  2. Leetcode Biweekly Contest 51 | Closest Room | Seat Reservation Manager | LEETCODE | CODE EXPLAINERcode Explainer · 20:24 · 1K views
  3. LeetCode 1847. Closest RoomHappy Coding · 24:08 · 1K views
  4. 1847. Closest Room (Leetcode Hard)Programming Live with Larry · 15:26 · 725 views
  5. 【每日一题】1847. Closest Room, 5/5/2021Huifeng Guan · 17:48 · 351 views
  6. LeetCode 1847. Closest Room | Biweekly Contest 51宰相小甘罗 · 5:53 · 217 views
  7. LeetCode 1847. Closest Room 中文 | Biweekly Contest 51宰相小甘罗 · 6:09 · 98 views
  8. LeetCode Hard 1847 Closest Roomrobzingcod · 13:14 · 25 views
  9. 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, where abs(x) is the absolute value of x.

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.length
  • 1 <= n <= 105
  • k == queries.length
  • 1 <= k <= 104
  • 1 <= roomIdi, preferredj <= 107
  • 1 <= 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 answer
import 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.

Complexity

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.

Try this approach in the editor

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.

Complexity

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.

Try this approach in the editor

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
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
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.
Space Complexity: O(n), for storing room IDs in a sorted set.

Binary Search with Sorting

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.

Offline Query + Ordered Set + Binary Search–

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute Force ScanO(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 IDsO((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.

Comments

Now write it yourselfClose this page and solve Closest Room in the editor, without looking.
Practise Closest Room