大家好,欢迎来到无限大的频道
今天继续给大家带来力扣每日一题的题解
题目描述(中等):
座位预约管理系统
请你设计一个管理 n 个座位预约的系统,座位编号从 1 到 n 。
请你实现 SeatManager 类:
- SeatManager(int n) 初始化一个 SeatManager 对象,它管理从 1 到 n 编号的 n 个座位。所有座位初始都是可预约的。
- int reserve() 返回可以预约座位的 最小编号 ,此座位变为不可预约。
- void unreserve(int seatNumber) 将给定编号 seatNumber 对应的座位变成可以预约。
题目解析
在这个题目中,我们需要实现一个管理座位预约的系统,该系统能够处理从1到n的座位编号。主要有两个操作:预约座位和取消预约座位。我们需要高效地实现这两个操作,特别是能够快速获取最小可预约的座位。
设计思路
-
预约座位:需要返回当前可以预约的最小座位编号。为了快速访问最小座位,我们可以使用最小堆(min-heap),在堆中总是能够以O(1)的时间复杂度获取到最小元素,并能够在O(log n)的时间复杂度内将元素从堆中移除。
-
取消预约:当我们取消某个座位的预约时,需要将这个座位编号重新加入到可预约的座位中,这个操作在最小堆中同样是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语言中,虽然没有标准库中的最小堆,但我们可以使用动态排序数组或自己实现一个堆。以下是使用简单数组的思路:
- 使用一个布尔数组来跟踪每个座位是否被预约。预约时,线性查找找到未预约的最小座位。
- 取消预约时,简单地将相应的索引标记为未预约。
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++中的最小堆)以提高性能。