[LeetCode] 1847. Closest Room
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.length
1 <= n <= 105
k == queries.length
1 <= k <= 104
1 <= roomIdi, preferredj <= 107
1 <= sizei, minSizej <= 107
最近的房间。
一个酒店里有 n 个房间,这些房间用二维整数数组 rooms 表示,其中 rooms[i] = [roomIdi, sizei] 表示有一个房间号为 roomIdi 的房间且它的面积为 sizei 。每一个房间号 roomIdi 保证是 独一无二 的。
同时给你 k 个查询,用二维数组 queries 表示,其中 queries[j] = [preferredj, minSizej] 。第 j 个查询的答案是满足如下条件的房间 id :
房间的面积 至少 为 minSizej ,且
abs(id - preferredj) 的值 最小 ,其中 abs(x) 是 x 的绝对值。
如果差的绝对值有 相等 的,选择 最小 的 id 。如果 没有满足条件的房间 ,答案为 -1 。请你返回长度为 k 的数组 answer ,其中 answer[j] 为第 j 个查询的结果。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/closest-room
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题我暂时提供一个排序 + treeset的做法。题目说的有点绕,我重新解释一下。有 N 个房间,能拿到的信息是 id 和 roomSize;对于每一个 query,也包含两个信息,[preferredId, minSize],表示一个人 prefer 的房间号和这个人要求的最小的 roomSize。因为 queries 是一次性一起给出来的,所以我这里的思路是需要对两个 input 数组排序,尽量把 roomSize 大的房间分配给需求大的人,同时我也把roomSize大的房间尽量放在前面。
这时候我还需要一个 treeset,同时开始遍历 queries。对于每一个 query,只有当房间size满足当前这个人的 minSize,我才把 roomId 加入treeset。这样当我把满足当前这个人的 minSize 的所有房间 ID 都记录好之后,我再利用treeset的函数去找到往上和往下最接近 preferredId 的房间号。
如果对 treeset 的用法不清楚,自己查一下 floor() 和 ceiling() 这两个函数的定义。
时间O(nlogn)
空间O(n)
Java实现
1 class Solution { 2 public int[] closestRoom(int[][] rooms, int[][] queries) { 3 int[] res = new int[queries.length]; 4 int[][] qs = new int[queries.length][]; 5 for (int i = 0; i < queries.length; i++) { 6 // { preferredID, minSize, i } 7 qs[i] = new int[] { queries[i][0], queries[i][1], i }; 8 } 9 // 按room size从大到小排序 10 Arrays.sort(rooms, (a, b) -> b[1] - a[1]); 11 // 按minSize从大到小排序 12 Arrays.sort(qs, (a, b) -> b[1] - a[1]); 13 14 int i = 0; 15 TreeSet<Integer> treeset = new TreeSet<>(); 16 for (int[] q : qs) { 17 for (; i < rooms.length && rooms[i][1] >= q[1]; i++) { 18 treeset.add(rooms[i][0]); 19 } 20 Integer ans1 = treeset.floor(q[0]); 21 Integer ans2 = treeset.ceiling(q[0]); 22 if (ans1 != null && ans2 != null) { 23 res[q[2]] = q[0] - ans1 <= ans2 - q[0] ? ans1 : ans2; 24 } else { 25 res[q[2]] = ans1 == null && ans2 == null ? -1 : ans1 == null ? ans2 : ans1; 26 } 27 } 28 return res; 29 } 30 }