Design a system that manages the reservation state of n seats that are numbered from 1 to n.
Implement the SeatManager class:
SeatManager(int n) Initializes a SeatManager object that will manage n seats numbered from 1 to n. All seats are initially available.
int reserve() Fetches the smallest-numbered unreserved seat, reserves it, and returns its number.
void unreserve(int seatNumber) Unreserves the seat with the given seatNumber.
Example 1:
Input
["SeatManager", "reserve", "reserve", "unreserve", "reserve", "reserve", "reserve", "reserve", "unreserve"]
[[5], [], [], [2], [], [], [], [], [5]]
Output
[null, 1, 2, null, 2, 3, 4, 5, null]
Explanation
SeatManager seatManager = new SeatManager(5); // Initializes a SeatManager with 5 seats.
seatManager.reserve(); // All seats are available, so return the lowest numbered seat, which is 1.
seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2.
seatManager.unreserve(2); // Unreserve seat 2, so now the available seats are [2,3,4,5].
seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2.
seatManager.reserve(); // The available seats are [3,4,5], so return the lowest of them, which is 3.
seatManager.reserve(); // The available seats are [4,5], so return the lowest of them, which is 4.
seatManager.reserve(); // The only available seat is seat 5, so return 5.
seatManager.unreserve(5); // Unreserve seat 5, so now the available seats are [5].
Constraints:
1 <= n <= 105
1 <= seatNumber <= n
For each call to reserve, it is guaranteed that there will be at least one unreserved seat.
For each call to unreserve, it is guaranteed that seatNumber will be reserved.
At most 105 calls in total will be made to reserve and unreserve.
Solutions
Solution 1: Priority Queue (Min-Heap)
We define a priority queue (min-heap) \(\textit{q}\) to store all the available seat numbers. Initially, we add all seat numbers from \(1\) to \(n\) into \(\textit{q}\).
When calling the reserve method, we pop the top element from \(\textit{q}\), which is the smallest available seat number.
When calling the unreserve method, we add the seat number back into \(\textit{q}\).
In terms of time complexity, the initialization time complexity is \(O(n)\) or \(O(n \times \log n)\), and the time complexity of the reserve and unreserve methods is both \(O(\log n)\). The space complexity is \(O(n)\).
1 2 3 4 5 6 7 8 9101112131415
classSeatManager:def__init__(self,n:int):self.q=list(range(1,n+1))defreserve(self)->int:returnheappop(self.q)defunreserve(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 9101112131415161718192021222324
classSeatManager{privatePriorityQueue<Integer>q=newPriorityQueue<>();publicSeatManager(intn){for(inti=1;i<=n;++i){q.offer(i);}}publicintreserve(){returnq.poll();}publicvoidunreserve(intseatNumber){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); */
classSeatManager{public:SeatManager(intn){for(inti=1;i<=n;++i){q.push(i);}}intreserve(){intseat=q.top();q.pop();returnseat;}voidunreserve(intseatNumber){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); */
typeSeatManagerstruct{qhp}funcConstructor(nint)SeatManager{q:=hp{}fori:=1;i<=n;i++{heap.Push(&q,i)}returnSeatManager{q}}func(this*SeatManager)Reserve()int{returnheap.Pop(&this.q).(int)}func(this*SeatManager)Unreserve(seatNumberint){heap.Push(&this.q,seatNumber)}typehpstruct{sort.IntSlice}func(hhp)Less(i,jint)bool{returnh.IntSlice[i]<h.IntSlice[j]}func(h*hp)Push(vany){h.IntSlice=append(h.IntSlice,v.(int))}func(h*hp)Pop()any{a:=h.IntSlicev:=a[len(a)-1]h.IntSlice=a[:len(a)-1]returnv}/** * 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 9101112131415161718192021222324
classSeatManager{privateq:typeofMinPriorityQueue;constructor(n:number){this.q=newMinPriorityQueue();for(leti=1;i<=n;i++){this.q.enqueue(i);}}reserve():number{returnthis.q.dequeue().element;}unreserve(seatNumber:number):void{this.q.enqueue(seatNumber);}}/** * Your SeatManager object will be instantiated and called as such: * var obj = new SeatManager(n) * var param_1 = obj.reserve() * obj.unreserve(seatNumber) */
1 2 3 4 5 6 7 8 9101112131415161718192021222324
publicclassSeatManager{privatePriorityQueue<int,int>q=newPriorityQueue<int,int>();publicSeatManager(intn){for(inti=1;i<=n;++i){q.Enqueue(i,i);}}publicintReserve(){returnq.Dequeue();}publicvoidUnreserve(intseatNumber){q.Enqueue(seatNumber,seatNumber);}}/** * Your SeatManager object will be instantiated and called as such: * SeatManager obj = new SeatManager(n); * int param_1 = obj.Reserve(); * obj.Unreserve(seatNumber); */