力扣LeetCode: 1845 座位预约管理系统

题目:

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

请你实现 SeatManager 类:

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

示例 1:

输入:
["SeatManager", "reserve", "reserve", "unreserve", "reserve", "reserve", "reserve", "reserve", "unreserve"]
[[5], [], [], [2], [], [], [], [], [5]]
输出:
[null, 1, 2, null, 2, 3, 4, 5, null]

解释:
SeatManager seatManager = new SeatManager(5); // 初始化 SeatManager ,有 5 个座位。
seatManager.reserve();    // 所有座位都可以预约,所以返回最小编号的座位,也就是 1 。
seatManager.reserve();    // 可以预约的座位为 [2,3,4,5] ,返回最小编号的座位,也就是 2 。
seatManager.unreserve(2); // 将座位 2 变为可以预约,现在可预约的座位为 [2,3,4,5] 。
seatManager.reserve();    // 可以预约的座位为 [2,3,4,5] ,返回最小编号的座位,也就是 2 。
seatManager.reserve();    // 可以预约的座位为 [3,4,5] ,返回最小编号的座位,也就是 3 。
seatManager.reserve();    // 可以预约的座位为 [4,5] ,返回最小编号的座位,也就是 4 。
seatManager.reserve();    // 唯一可以预约的是座位 5 ,所以返回 5 。
seatManager.unreserve(5); // 将座位 5 变为可以预约,现在可预约的座位为 [5] 。

提示:

  • 1 <= n <= 10^5
  • 1 <= seatNumber <= n
  • 每一次对 reserve 的调用,题目保证至少存在一个可以预约的座位。
  • 每一次对 unreserve 的调用,题目保证 seatNumber 在调用函数前都是被预约状态。
  • 对 reserve 和 unreserve 的调用 总共 不超过 10^5 次。

解法:优先队列

        priority_queue的底层通常使用堆(heap)数据结构来实现。堆是一种二叉树的数据结构(堆,数据结构详细介绍链接),具有以下特点:

        堆结构是一个完全二叉树(Complete Binary Tree),即除了最后一层外,其他层都必须是满的,且最后一层的结点都靠左排列。

        二叉堆分为最大堆(Max Heap)和最小堆(Min Heap)两种类型。

最大堆:每个父节点的值都大于或等于其子节点的值,即根节点的值最大。
最小堆:每个父节点的值都小于或等于其子节点的值,即根节点的值最小。
        在priority_queue中,默认情况下采用最大堆实现,即优先级最高的元素存储在根节点,根节点的值最大。根据堆的性质,保证了在插入元素时,优先队列会根据元素的优先级进行自动排序,并在取出元素时能够取出优先级最高的元素。
其实是优化了排序,第一次写的时候使用的是sort,超时了。二叉的话就快。

使用大顶堆的队列:
        priority_queue,less> q;//储存int型数据 
        priority_queue,less> q;//储存double型数据 
        priority_queue,less> q;//储存string型数据 
        priority_queue<结构体名,vector<结构体名>,less<结构体名>> q;//储存结构体或者类 

使用小顶堆的队列:
        priority_queue,greater> q;//储存int型数据
        priority_queue,greater> q;//储存double型数据
        priority_queue,greater> q;//储存string型数据
        priority_queue<结构体名,vector<结构体名>,greater<结构体名>> q;//储存结构体或者类 

时间复杂度: 
O(n+(q1​+q2​)logn)

空间复杂度: 
O(n)


class SeatManager {
public:
    std::priority_queue, std::greater> num;
    SeatManager(int n) {
        for(int i = 1; i <= n; i++)
        {
            num.push(i);
        }
    }
    
    int reserve() {
        int number = num.top();
        num.pop();
        return number;
    }
    
    void unreserve(int seatNumber) {
        num.push(seatNumber);
    }
};

你可能感兴趣的:(LeetCode,leetcode)