80
80
81
81
<!-- solution:start -->
82
82
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$ 为朋友的个数。
84
92
85
93
<!-- tabs:start -->
86
94
@@ -90,20 +98,19 @@ tags:
90
98
class Solution :
91
99
def smallestChair (self , times : List[List[int ]], targetFriend : int ) -> int :
92
100
n = len (times)
93
- h = list (range (n))
94
- heapify(h)
95
101
for i in range (n):
96
102
times[i].append(i)
97
103
times.sort()
104
+ idle = list (range (n))
105
+ heapify(idle)
98
106
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 )
103
111
if i == targetFriend:
104
- return c
105
- heappush(busy, (b, c))
106
- return - 1
112
+ return j
113
+ heappush(busy, (leaving, j))
107
114
```
108
115
109
116
#### Java
@@ -112,24 +119,23 @@ class Solution:
112
119
class Solution {
113
120
public int smallestChair (int [][] times , int targetFriend ) {
114
121
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 ]));
118
124
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);
121
127
}
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 ]);
127
133
}
128
- int c = q . poll();
134
+ int j = idle . poll();
129
135
if (i == targetFriend) {
130
- return c ;
136
+ return j ;
131
137
}
132
- busy. offer(new int [] {b, c });
138
+ busy. offer(new int [] {leaving, j });
133
139
}
134
140
return - 1 ;
135
141
}
@@ -139,35 +145,138 @@ class Solution {
139
145
#### C++
140
146
141
147
``` cpp
142
- using pii = pair<int , int >;
143
-
144
148
class Solution {
145
149
public:
146
150
int smallestChair(vector<vector<int >>& times, int targetFriend) {
147
- priority_queue<int, vector <int >, greater< int >> q ;
151
+ using pii = pair <int, int>;
148
152
priority_queue<pii, vector<pii >, greater<pii >> busy;
153
+ priority_queue<int, vector<int >, greater<int >> idle;
149
154
int n = times.size();
150
155
for (int i = 0; i < n; ++i) {
151
156
times[ i] .push_back(i);
152
- q .push(i);
157
+ idle .push(i);
153
158
}
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);
159
164
busy.pop();
160
165
}
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);
165
172
}
166
173
return -1;
167
174
}
168
175
};
169
176
```
170
177
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
+
171
280
<!-- tabs: end -->
172
281
173
282
<!-- solution: end -->
0 commit comments