跳转至

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

解法

方法一:优先队列(小根堆)

我们可以使用优先队列(小根堆)来维护可预约座位的最小编号。

初始化时,将所有座位的编号放入优先队列中。

当调用 reserve 方法时,从优先队列中取出最小编号的座位,即为可预约座位的最小编号。

当调用 unreserve 方法时,将座位编号放入优先队列中。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为座位的数量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class SeatManager:
    def __init__(self, n: int):
        self.q = list(range(1, n + 1))
        heapify(self.q)

    def reserve(self) -> int:
        return heappop(self.q)

    def unreserve(self, seatNumber: int) -> None:
        heappush(self.q, seatNumber)


# Your SeatManager object will be instantiated and called as such:
# obj = SeatManager(n)
# param_1 = obj.reserve()
# obj.unreserve(seatNumber)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SeatManager {
    private PriorityQueue<Integer> q = new PriorityQueue<>();

    public SeatManager(int n) {
        for (int i = 1; i <= n; ++i) {
            q.offer(i);
        }
    }

    public int reserve() {
        return q.poll();
    }

    public void unreserve(int seatNumber) {
        q.offer(seatNumber);
    }
}

/**
 * Your SeatManager object will be instantiated and called as such:
 * SeatManager obj = new SeatManager(n);
 * int param_1 = obj.reserve();
 * obj.unreserve(seatNumber);
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class SeatManager {
public:
    SeatManager(int n) {
        for (int i = 1; i <= n; ++i) {
            q.push(i);
        }
    }

    int reserve() {
        int seat = q.top();
        q.pop();
        return seat;
    }

    void unreserve(int seatNumber) {
        q.push(seatNumber);
    }

private:
    priority_queue<int, vector<int>, greater<int>> q;
};

/**
 * Your SeatManager object will be instantiated and called as such:
 * SeatManager* obj = new SeatManager(n);
 * int param_1 = obj->reserve();
 * obj->unreserve(seatNumber);
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type SeatManager struct {
    q hp
}

func Constructor(n int) SeatManager {
    q := hp{}
    for i := 1; i <= n; i++ {
        heap.Push(&q, i)
    }
    return SeatManager{q}
}

func (this *SeatManager) Reserve() int {
    return heap.Pop(&this.q).(int)
}

func (this *SeatManager) Unreserve(seatNumber int) {
    heap.Push(&this.q, seatNumber)
}

type hp struct{ sort.IntSlice }

func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
func (h *hp) Push(v any)        { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() any {
    a := h.IntSlice
    v := a[len(a)-1]
    h.IntSlice = a[:len(a)-1]
    return v
}

/**
 * Your SeatManager object will be instantiated and called as such:
 * obj := Constructor(n);
 * param_1 := obj.Reserve();
 * obj.Unreserve(seatNumber);
 */
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class SeatManager {
    private SortedSet<int> availableSeats;

    public SeatManager(int n) {
        availableSeats = new SortedSet<int>();
        for (int i = 1; i <= n; i++) {
            availableSeats.Add(i);
        }
    }

    public int Reserve() {
        int reservedSeat = availableSeats.Min;
        availableSeats.Remove(reservedSeat);
        return reservedSeat;
    }

    public void Unreserve(int seatNumber) {
        availableSeats.Add(seatNumber);
    }
}

/**
 * Your SeatManager object will be instantiated and called as such:
 * SeatManager obj = new SeatManager(n);
 * int param_1 = obj.Reserve();
 * obj.Unreserve(seatNumber);
 */

评论