8080
8181<!-- solution:start -->
8282
83- ### 方法一:优先队列(最小堆)
83+ ### 方法一:优先队列(小根堆)
84+
85+ 我们首先将每个朋友的到达时间、离开时间和编号组成一个三元组,然后按到达时间排序。
86+
87+ 我们使用一个小根堆 $\textit{idle}$ 来存储当前空闲的椅子编号,初始时,我们将 $0, 1, \ldots, n-1$ 加入 $\textit{idle}$ 中。使用一个小根堆 $\textit{busy}$ 存储二元组 $(\textit{leaving}, \textit{chair})$,其中 $\textit{leaving}$ 表示离开时间,而 $\textit{chair}$ 表示椅子编号。
88+
89+ 遍历每个朋友的到达时间、离开时间和编号,对于每个朋友,我们首先将所有离开时间小于等于当前朋友到达时间的朋友从 $\textit{busy}$ 中弹出,将他们占据的椅子编号加入 $\textit{idle}$ 中。然后我们从 $\textit{idle}$ 中弹出一个椅子编号,将其分配给当前朋友,将 $(\textit{leaving}, \textit{chair})$ 加入 $\textit{busy}$ 中。如果当前朋友的编号等于 $\textit{targetFriend}$,我们返回当前分配的椅子编号。
90+
91+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为朋友的个数。
8492
8593<!-- tabs:start -->
8694
@@ -90,20 +98,19 @@ tags:
9098class Solution :
9199 def smallestChair (self , times : List[List[int ]], targetFriend : int ) -> int :
92100 n = len (times)
93- h = list (range (n))
94- heapify(h)
95101 for i in range (n):
96102 times[i].append(i)
97103 times.sort()
104+ idle = list (range (n))
105+ heapify(idle)
98106 busy = []
99- for a, b , i in times:
100- while busy and busy[0 ][0 ] <= a :
101- heappush(h , heappop(busy)[1 ])
102- c = heappop(h )
107+ for arrival, leaving , i in times:
108+ while busy and busy[0 ][0 ] <= arrival :
109+ heappush(idle , heappop(busy)[1 ])
110+ j = heappop(idle )
103111 if i == targetFriend:
104- return c
105- heappush(busy, (b, c))
106- return - 1
112+ return j
113+ heappush(busy, (leaving, j))
107114```
108115
109116#### Java
@@ -112,24 +119,23 @@ class Solution:
112119class Solution {
113120 public int smallestChair (int [][] times , int targetFriend ) {
114121 int n = times. length;
115- int [][] ts = new int [n][3 ];
116- PriorityQueue<Integer > q = new PriorityQueue<> ();
117- PriorityQueue<int[]> busy = new PriorityQueue<> ((a, b) - > a[0 ] - b[0 ]);
122+ PriorityQueue<Integer > idle = new PriorityQueue<> ();
123+ PriorityQueue<int[]> busy = new PriorityQueue<> (Comparator . comparingInt(a - > a[0 ]));
118124 for (int i = 0 ; i < n; ++ i) {
119- ts [i] = new int [] {times[i][0 ], times[i][1 ], i};
120- q . offer(i);
125+ times [i] = new int [] {times[i][0 ], times[i][1 ], i};
126+ idle . offer(i);
121127 }
122- Arrays . sort(ts, (a, b) - > a[0 ] - b[ 0 ] );
123- for (int [] t : ts ) {
124- int a = t [0 ], b = t [1 ], i = t [2 ];
125- while (! busy. isEmpty() && busy. peek()[0 ] <= a ) {
126- q . offer(busy. poll()[1 ]);
128+ Arrays . sort(times, Comparator . comparingInt(a - > a[0 ]) );
129+ for (var e : times ) {
130+ int arrival = e [0 ], leaving = e [1 ], i = e [2 ];
131+ while (! busy. isEmpty() && busy. peek()[0 ] <= arrival ) {
132+ idle . offer(busy. poll()[1 ]);
127133 }
128- int c = q . poll();
134+ int j = idle . poll();
129135 if (i == targetFriend) {
130- return c ;
136+ return j ;
131137 }
132- busy. offer(new int [] {b, c });
138+ busy. offer(new int [] {leaving, j });
133139 }
134140 return - 1 ;
135141 }
@@ -139,35 +145,138 @@ class Solution {
139145#### C++
140146
141147``` cpp
142- using pii = pair<int , int >;
143-
144148class Solution {
145149public:
146150 int smallestChair(vector<vector<int >>& times, int targetFriend) {
147- priority_queue<int, vector <int >, greater< int >> q ;
151+ using pii = pair <int, int>;
148152 priority_queue<pii, vector<pii >, greater<pii >> busy;
153+ priority_queue<int, vector<int >, greater<int >> idle;
149154 int n = times.size();
150155 for (int i = 0; i < n; ++i) {
151156 times[ i] .push_back(i);
152- q .push(i);
157+ idle .push(i);
153158 }
154- sort(times.begin(), times.end() );
155- for (auto& t : times) {
156- int a = t [ 0] , b = t [ 1] , i = t [ 2] ;
157- while (!busy.empty() && busy.top().first <= a ) {
158- q .push(busy.top().second);
159+ ranges:: sort(times);
160+ for (const auto& e : times) {
161+ int arrival = e [ 0] , leaving = e [ 1] , i = e [ 2] ;
162+ while (!busy.empty() && busy.top().first <= arrival ) {
163+ idle .push(busy.top().second);
159164 busy.pop();
160165 }
161- int c = q.top();
162- q.pop();
163- if (i == targetFriend) return c;
164- busy.push({b, c});
166+ int j = idle.top();
167+ if (i == targetFriend) {
168+ return j;
169+ }
170+ idle.pop();
171+ busy.emplace(leaving, j);
165172 }
166173 return -1;
167174 }
168175};
169176```
170177
178+ #### Go
179+
180+ ```go
181+ func smallestChair(times [][]int, targetFriend int) int {
182+ idle := hp{}
183+ busy := hp2{}
184+ for i := range times {
185+ times[i] = append(times[i], i)
186+ heap.Push(&idle, i)
187+ }
188+ sort.Slice(times, func(i, j int) bool { return times[i][0] < times[j][0] })
189+ for _, e := range times {
190+ arrival, leaving, i := e[0], e[1], e[2]
191+ for len(busy) > 0 && busy[0].t <= arrival {
192+ heap.Push(&idle, heap.Pop(&busy).(pair).i)
193+ }
194+ j := heap.Pop(&idle).(int)
195+ if i == targetFriend {
196+ return j
197+ }
198+ heap.Push(&busy, pair{leaving, j})
199+ }
200+ return -1
201+ }
202+
203+ type hp struct{ sort.IntSlice }
204+
205+ func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
206+ func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
207+ func (h *hp) Pop() any {
208+ a := h.IntSlice
209+ v := a[len(a)-1]
210+ h.IntSlice = a[:len(a)-1]
211+ return v
212+ }
213+
214+ type pair struct{ t, i int }
215+ type hp2 []pair
216+
217+ func (h hp2) Len() int { return len(h) }
218+ func (h hp2) Less(i, j int) bool { return h[i].t < h[j].t || (h[i].t == h[j].t && h[i].i < h[j].i) }
219+ func (h hp2) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
220+ func (h *hp2) Push(v any) { *h = append(*h, v.(pair)) }
221+ func (h *hp2) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
222+ ```
223+
224+ #### TypeScript
225+
226+ ``` ts
227+ function smallestChair(times : number [][], targetFriend : number ): number {
228+ const n = times .length ;
229+ const idle = new MinPriorityQueue ();
230+ const busy = new MinPriorityQueue ({ priority : v => v [0 ] });
231+ for (let i = 0 ; i < n ; ++ i ) {
232+ times [i ].push (i );
233+ idle .enqueue (i );
234+ }
235+ times .sort ((a , b ) => a [0 ] - b [0 ]);
236+ for (const [arrival, leaving, i] of times ) {
237+ while (busy .size () > 0 && busy .front ().element [0 ] <= arrival ) {
238+ idle .enqueue (busy .dequeue ().element [1 ]);
239+ }
240+ const j = idle .dequeue ().element ;
241+ if (i === targetFriend ) {
242+ return j ;
243+ }
244+ busy .enqueue ([leaving , j ]);
245+ }
246+ return - 1 ;
247+ }
248+ ```
249+
250+ #### JavaScript
251+
252+ ``` js
253+ /**
254+ * @param {number[][]} times
255+ * @param {number} targetFriend
256+ * @return {number}
257+ */
258+ var smallestChair = function (times , targetFriend ) {
259+ const n = times .length ;
260+ const idle = new MinPriorityQueue ();
261+ const busy = new MinPriorityQueue ({ priority : v => v[0 ] });
262+ for (let i = 0 ; i < n; ++ i) {
263+ times[i].push (i);
264+ idle .enqueue (i);
265+ }
266+ times .sort ((a , b ) => a[0 ] - b[0 ]);
267+ for (const [arrival , leaving , i ] of times) {
268+ while (busy .size () > 0 && busy .front ().element [0 ] <= arrival) {
269+ idle .enqueue (busy .dequeue ().element [1 ]);
270+ }
271+ const j = idle .dequeue ().element ;
272+ if (i === targetFriend) {
273+ return j;
274+ }
275+ busy .enqueue ([leaving, j]);
276+ }
277+ };
278+ ```
279+
171280<!-- tabs: end -->
172281
173282<!-- solution: end -->
0 commit comments