最近的房间
难度:
标签:
题目描述
代码结果
运行时间: 236 ms, 内存: 53.5 MB
/*
* 思路:
* 1. 首先,我们需要对房间按照面积进行排序,这样可以快速找到满足面积条件的房间。
* 2. 然后,我们对每个查询进行处理,找到所有满足面积条件的房间,并选择房间号最接近 preferred 的那个房间。
* 3. 如果有多个房间号的绝对差值相同,选择房间号最小的那个。
* 4. 如果没有满足条件的房间,返回 -1。
*/
import java.util.*;
import java.util.stream.Collectors;
public class HotelRoomsStream {
public int[] closestRoom(int[][] rooms, int[][] queries) {
List<int[]> roomList = Arrays.stream(rooms)
.sorted(Comparator.comparingInt(room -> room[1]))
.collect(Collectors.toList()); // 按面积排序
int k = queries.length;
int[] result = new int[k];
TreeSet<Integer> roomIds = new TreeSet<>(); // 用于快速查找最近的房间号
int i = 0;
for (int j = 0; j < k; j++) {
int preferred = queries[j][0];
int minSize = queries[j][1];
// 将所有面积大于等于 minSize 的房间号添加到 TreeSet 中
while (i < roomList.size() && roomList.get(i)[1] < minSize) {
i++;
}
while (i < roomList.size()) {
roomIds.add(roomList.get(i)[0]);
i++;
}
// 在 TreeSet 中查找距离 preferred 最近的房间号
Integer lower = roomIds.floor(preferred); // <= preferred 的最大房间号
Integer higher = roomIds.ceiling(preferred); // >= preferred 的最小房间号
if (lower == null && higher == null) {
result[j] = -1;
} else if (lower == null) {
result[j] = higher;
} else if (higher == null) {
result[j] = lower;
} else {
if (Math.abs(lower - preferred) <= Math.abs(higher - preferred)) {
result[j] = lower;
} else {
result[j] = higher;
}
}
}
return result;
}
}
解释
方法:
本题解采用排序和二分查找的方法。首先,将房间按照面积从大到小排序,将查询按照最小面积从大到小排序。然后,遍历查询,对于每个查询,使用二分查找在已经满足面积要求的房间中找到最接近期望房间号的房间。具体而言,先二分插入所有满足面积要求的房间号,然后二分查找找到最接近期望房间号的房间。
时间复杂度:
O(m log m + n log n + n log m)
空间复杂度:
O(m + n)
代码细节讲解
🦆
为什么在处理查询前,需要先将房间按面积从大到小排序?
▷🦆
排序查询的目的是什么,它是如何帮助优化查找过程的?
▷🦆
在使用二分查找确定最接近的房间号时,如何处理有多个房间号与预期房间号距离相等的情况?
▷🦆
当`bisect.bisect_left`找到的索引`k`为0或`len(ids)`时,为什么直接选择`ids[0]`或`ids[-1]`作为结果?
▷