Leetcode打卡:最近的房间

执行结果:通过

题目:1847 最近的房间

一个酒店里有 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 个查询的结果。

示例 1:

复制代码
输入:rooms = [[2,2],[1,2],[3,2]], queries = [[3,1],[3,3],[5,2]]
输出:[3,-1,3]
解释:查询的答案如下:
查询 [3,1] :房间 3 的面积为 2 ,大于等于 1 ,且号码是最接近 3 的,为 abs(3 - 3) = 0 ,所以答案为 3 。
查询 [3,3] :没有房间的面积至少为 3 ,所以答案为 -1 。
查询 [5,2] :房间 3 的面积为 2 ,大于等于 2 ,且号码是最接近 5 的,为 abs(3 - 5) = 2 ,所以答案为 3 。

示例 2:

复制代码
输入:rooms = [[1,4],[2,3],[3,5],[4,1],[5,2]], queries = [[2,3],[2,4],[2,5]]
输出:[2,1,3]
解释:查询的答案如下:
查询 [2,3] :房间 2 的面积为 3 ,大于等于 3 ,且号码是最接近的,为 abs(2 - 2) = 0 ,所以答案为 2 。
查询 [2,4] :房间 1 和 3 的面积都至少为 4 ,答案为 1 因为它房间编号更小。
查询 [2,5] :房间 3 是唯一面积大于等于 5 的,所以答案为 3 

提示:

  • n == rooms.length
  • 1 <= n <= 105
  • k == queries.length
  • 1 <= k <= 104
  • 1 <= roomIdi, preferredj <= 107
  • 1 <= sizei, minSizej <= 107

代码以及解题思路

代码:

复制代码
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 int cmp(const void *a, const void *b) {
    int *m = *(int **)a, *n = *(int **)b;
    if (m[1] != n[1]) {
        return m[1] - n[1];
    }
    else {
        return m[0] - n[0];
    }
}

int* closestRoom(int** rooms, int roomsSize, int* roomsColSize, int** queries, int queriesSize, int* queriesColSize, int* returnSize) {
    int *res = (int *)malloc(sizeof(int) * queriesSize);
   *returnSize = queriesSize;
    qsort(rooms, roomsSize, sizeof(int *), cmp);
    
    int left, right;

    for (int i = 0; i < queriesSize; i++) {
        if (i > 0) { //这个地方优化最后2个测试用例,否则超时
            if (queries[i][1] == queries[i - 1][1] && queries[i][0] == queries[i - 1][0]) {
                res[i] = res[i - 1];
                continue;
            }
        }
        left = 0;
        right = roomsSize - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (rooms[mid][1] >= queries[i][1]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }

        if (right == roomsSize - 1) {
            res[i] = -1;
            continue;
        }

        left = right + 1;
        right = roomsSize - 1;
        int absVal = abs(queries[i][0] - rooms[left][0]);
        res[i] = rooms[left][0];
        for (int j = left + 1; j <= right; j++) {
            int temp = abs(queries[i][0] - rooms[j][0]);
            if (temp < absVal) {
                absVal = temp;
                res[i] = rooms[j][0];
            } else if (temp == absVal) {
                if (rooms[j][0] < res[i]) {
                    res[i] = rooms[j][0];
                }
            }
        }
    }

    return res; 

}

解题思路:

  1. 内存分配
    • 为结果数组 res 分配内存,其大小为 queriesSize,因为对于每个查询都需要一个结果。
    • 通过 *returnSize = queriesSize; 设置返回数组的大小。
  2. 排序
    • 使用 qsort 函数对 rooms 数组进行排序。排序的依据是房间的 y 坐标,如果 y 坐标相同,则按 x 坐标排序。这是为了确保在后续的二分查找中,我们可以快速定位到与查询 y 坐标最接近的房间。
  3. 遍历查询
    • 对于每个查询,首先检查是否与前一个查询相同(这是为了优化性能,避免对相同的查询进行重复计算)。如果相同,则直接使用前一个查询的结果。
    • 使用二分查找定位到 rooms 数组中第一个 y 坐标大于查询 y 坐标的房间的左侧位置(即该位置房间的 y 坐标小于或等于查询的 y 坐标,而下一个位置的 y 坐标大于查询的 y 坐标,或者该位置已经是数组的最后一个元素)。
  4. 处理边界情况
    • 如果二分查找的结果指向数组的最后一个元素,并且该元素的 y 坐标仍然小于查询的 y 坐标,则说明没有找到任何符合条件的房间,将结果设置为 -1。
  5. 在二分查找结果的基础上寻找最接近的房间
    • 从二分查找确定的左侧位置的下一个位置开始,遍历剩余的房间,找到与查询 x 坐标最接近的房间的 x 坐标。如果有多个房间与查询的 x 坐标距离相同,则选择 x 坐标最小的那个。
  6. 返回结果
    • 返回结果数组 res,其中包含了每个查询对应的最接近房间的 x 坐标或 -1(如果没有找到任何房间)。
相关推荐
TO ENFJ1 分钟前
day 17 无监督学习之聚类算法
学习·算法·聚类
GIS小天9 分钟前
AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月15日第78弹
人工智能·算法·机器学习·彩票
共享家952711 分钟前
红黑树解析
数据结构·c++·算法
边跑边掩护13 分钟前
LeetCode 820 单词的压缩编码题解
算法·leetcode·职场和发展
Espresso Macchiato15 分钟前
Leetcode 3543. Maximum Weighted K-Edge Path
leetcode·leetcode medium·图遍历·leetcode 3543·leetcode双周赛156
lingxiao168881 小时前
双目立体视觉
图像处理·算法·机器学习·计算机视觉
JNU freshman1 小时前
和为target问题汇总
算法
2401_859049081 小时前
MSPM0--Timer(一口一口喂版)
arm开发·单片机·mcu·算法
寂空_1 小时前
【算法笔记】ACM数论基础模板
c++·笔记·算法
ggabb1 小时前
当九九乘法口诀“出海”英国:文化碰撞下的数学教育变革
算法