力扣题解1845

大家好,欢迎来到无限大的频道

今天继续给大家带来力扣每日一题的题解

题目描述(中等):

座位预约管理系统

请你设计一个管理 n 个座位预约的系统,座位编号从 1 到 n 。

请你实现 SeatManager 类:

  • SeatManager(int n) 初始化一个 SeatManager 对象,它管理从 1 到 n 编号的 n 个座位。所有座位初始都是可预约的。
  • int reserve() 返回可以预约座位的 最小编号 ,此座位变为不可预约。
  • void unreserve(int seatNumber) 将给定编号 seatNumber 对应的座位变成可以预约。

题目解析

在这个题目中,我们需要实现一个管理座位预约的系统,该系统能够处理从1到n的座位编号。主要有两个操作:预约座位和取消预约座位。我们需要高效地实现这两个操作,特别是能够快速获取最小可预约的座位。

设计思路

  1. 预约座位:需要返回当前可以预约的最小座位编号。为了快速访问最小座位,我们可以使用最小堆(min-heap),在堆中总是能够以O(1)的时间复杂度获取到最小元素,并能够在O(log n)的时间复杂度内将元素从堆中移除。

  2. 取消预约:当我们取消某个座位的预约时,需要将这个座位编号重新加入到可预约的座位中,这个操作在最小堆中同样是O(log n)的复杂度。

时间复杂度与空间复杂度

  • 初始化:将所有座位编号插入最小堆,这个步骤的时间复杂度是O(n)。
  • 预约操作的时间复杂度是O(log n),因为需要从堆中弹出最小元素。
  • 取消预约操作的时间复杂度是O(log n),因为需要将元素插入到堆中。
  • 空间复杂度:O(n),用来存储最多n个座位的编号。

C++ 实现

以下是C++实现SeatManager类的代码示例:

class SeatManager {
public:
    SeatManager(int n) {
        for (int i = 1; i <= n; ++i) {
            availableSeats.push(i);  // 初始化最小堆,填充所有座位编号
        }
    }

    int reserve() {
        int seat = availableSeats.top(); // 获取最小可预约座位
        availableSeats.pop();            // 将该座位标记为不可预约
        return seat;
    }

    void unreserve(int seatNumber) {
        availableSeats.push(seatNumber); // 将座位号码添加回可预约座位中
    }

private:
    std::priority_queue<int, std::vector<int>, std::greater<int>> availableSeats; // 最小堆
};

C 语言实现

在C语言中,虽然没有标准库中的最小堆,但我们可以使用动态排序数组或自己实现一个堆。以下是使用简单数组的思路:

  1. 使用一个布尔数组来跟踪每个座位是否被预约。预约时,线性查找找到未预约的最小座位。
  2. 取消预约时,简单地将相应的索引标记为未预约。
typedef struct {
    bool* reserved;
    int size;
} SeatManager;

SeatManager* seatManagerCreate(int n) {
    SeatManager* obj = (SeatManager*)malloc(sizeof(SeatManager));
    obj->reserved = (bool*)calloc(n + 1, sizeof(bool)); // 创建一个大小为n+1的布尔数组
    obj->size = n;
    return obj;
}

int seatManagerReserve(SeatManager* obj) {
    for (int i = 1; i <= obj->size; ++i) {
        if (!obj->reserved[i]) { // 查找第一个未预约的座位
            obj->reserved[i] = true;
            return i; // 返回该座位编号
        }
    }
    return -1; // 如果没有可预约的座位,返回-1(边界情况)
}

void seatManagerUnreserve(SeatManager* obj, int seatNumber) {
    obj->reserved[seatNumber] = false; // 将对应的座位标记为可预约
}

void seatManagerFree(SeatManager* obj) {
    free(obj->reserved);
    free(obj); // 释放内存
}

总结

C++的最小堆实现能够高效地支持预约和取消预约操作,时间复杂度均为O(log n)。而C语言的实现则使用了数组,虽然简单易懂,但预约操作的时间复杂度为O(n),不适合处理较大座位数量的情况。在实际开发中,通常建议使用更高效的实现(如C++中的最小堆)以提高性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值