@@ -79,13 +79,13 @@ tags:
79
79
80
80
### 方法一:优先队列(小根堆)
81
81
82
- 定义两个优先级队列,分别表示空闲服务器、使用中的服务器。其中:空闲服务器 ` idle ` 依据 ** 权重、下标 ** 排序;而使用中的服务器 ` busy ` 依据 ** 结束时间、权重、下标 ** 排序 。
82
+ 我们用一个小根堆 $\textit{ idle}$ 来维护所有的空闲服务器,其中每个元素是一个二元组 $(x, i)$,表示第 $i$ 台服务器的权重为 $x$。用一个小根堆 $\textit{ busy}$ 来维护所有的忙碌服务器,其中每个元素是一个三元组 $(w, s, i)$,表示第 $i$ 台服务器在第 $w$ 秒恢复空闲,权重为 $s$。初始时我们将所有的服务器加入到 $\textit{idle}$ 中 。
83
83
84
- 遍历任务:
84
+ 接下来,我们遍历所有的任务,对于第 $j$ 项任务,我们首先将所有在第 $j$ 秒或之前恢复空闲的服务器从 $\textit{busy}$ 中移除,添加到 $\textit{idle}$ 中。然后我们从 $\textit{idle}$ 中取出一个权重最小的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。如果 $\textit{idle}$ 为空,我们从 $\textit{busy}$ 中取出一个恢复时间最早的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。
85
85
86
- - 若有使用中的服务器小于任务开始时间,将其加入到空闲服务器队列 ` idle ` 中;
87
- - 若当前有空闲服务器,那么在空闲队列 ` idle ` 中取出权重最小的服务器,将其加入使用中的队列 ` busy ` 中;
88
- - 若当前没有空闲服务器,那么在使用队列 ` busy ` 中找出最早结束时间且权重最小的服务器,重新加入使用中的队列 ` busy ` 中 。
86
+ 遍历结束后,我们得到了答案数组 $\textit{ans}$。
87
+
88
+ 时间复杂度 $O((n + m) \log n)$,其中 $n$ 为服务器的数量,$m$ 为任务的数量。空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为服务器和任务的数量 。
89
89
90
90
相似题目:
91
91
@@ -98,61 +98,205 @@ tags:
98
98
``` python
99
99
class Solution :
100
100
def assignTasks (self , servers : List[int ], tasks : List[int ]) -> List[int ]:
101
- idle, busy = [], [ ]
102
- for i, weight in enumerate (servers):
103
- heappush(idle, (weight, i))
104
- res = []
105
- for start, cost in enumerate (tasks):
106
- while busy and busy[0 ][0 ] <= start :
101
+ idle = [(x, i) for i, x in enumerate (servers) ]
102
+ heapify(idle)
103
+ busy = []
104
+ ans = []
105
+ for j, t in enumerate (tasks):
106
+ while busy and busy[0 ][0 ] <= j :
107
107
_, s, i = heappop(busy)
108
108
heappush(idle, (s, i))
109
109
if idle:
110
110
s, i = heappop(idle)
111
- heappush(busy, (start + cost , s, i))
111
+ heappush(busy, (j + t , s, i))
112
112
else :
113
- t , s, i = heappop(busy)
114
- heappush(busy, (t + cost , s, i))
115
- res .append(i)
116
- return res
113
+ w , s, i = heappop(busy)
114
+ heappush(busy, (w + t , s, i))
115
+ ans .append(i)
116
+ return ans
117
117
```
118
118
119
119
#### Java
120
120
121
121
``` java
122
122
class Solution {
123
123
public int [] assignTasks (int [] servers , int [] tasks ) {
124
- int m = tasks. length, n = servers. length;
125
- PriorityQueue<int[]> idle
126
- = new PriorityQueue<> ((a, b) - > a[0 ] == b[0 ] ? a[1 ] - b[1 ] : a[0 ] - b[0 ]);
124
+ int n = servers. length;
125
+ PriorityQueue<int[]> idle = new PriorityQueue<> ((a, b) - > {
126
+ if (a[0 ] != b[0 ]) {
127
+ return a[0 ] - b[0 ];
128
+ }
129
+ return a[1 ] - b[1 ];
130
+ });
127
131
PriorityQueue<int[]> busy = new PriorityQueue<> ((a, b) - > {
128
- if (a[0 ] = = b[0 ]) {
129
- return a[1 ] == b[ 1 ] ? a[ 2 ] - b[2 ] : a[ 1 ] - b[ 1 ];
132
+ if (a[0 ] ! = b[0 ]) {
133
+ return a[0 ] - b[0 ];
130
134
}
131
- return a[0 ] - b[0 ];
135
+ if (a[1 ] != b[1 ]) {
136
+ return a[1 ] - b[1 ];
137
+ }
138
+ return a[2 ] - b[2 ];
132
139
});
133
- for (int i = 0 ; i < n; ++ i ) {
140
+ for (int i = 0 ; i < n; i ++ ) {
134
141
idle. offer(new int [] {servers[i], i});
135
142
}
136
- int [] res = new int [m] ;
137
- int j = 0 ;
138
- for (int start = 0 ; start < m; ++ start ) {
139
- int cost = tasks[start ];
140
- while (! busy. isEmpty() && busy. peek()[0 ] <= start ) {
141
- int [] item = busy. poll();
142
- idle. offer(new int [] {item [1 ], item [2 ]});
143
+ int m = tasks . length ;
144
+ int [] ans = new int [m] ;
145
+ for (int j = 0 ; j < m; ++ j ) {
146
+ int t = tasks[j ];
147
+ while (! busy. isEmpty() && busy. peek()[0 ] <= j ) {
148
+ int [] p = busy. poll();
149
+ idle. offer(new int [] {p [1 ], p [2 ]});
143
150
}
144
151
if (! idle. isEmpty()) {
145
- int [] item = idle. poll();
146
- res[j ++ ] = item[ 1 ] ;
147
- busy. offer(new int [] {start + cost, item[ 0 ], item[ 1 ] });
152
+ int i = idle. poll()[ 1 ] ;
153
+ ans[j ] = i ;
154
+ busy. offer(new int [] {j + t, servers[i ], i });
148
155
} else {
149
- int [] item = busy. poll();
150
- res[j++ ] = item[2 ];
151
- busy. offer(new int [] {item[0 ] + cost, item[1 ], item[2 ]});
156
+ int [] p = busy. poll();
157
+ int i = p[2 ];
158
+ ans[j] = i;
159
+ busy. offer(new int [] {p[0 ] + t, p[1 ], i});
152
160
}
153
161
}
154
- return res;
162
+ return ans;
163
+ }
164
+ }
165
+ ```
166
+
167
+ #### C++
168
+
169
+ ``` cpp
170
+ class Solution {
171
+ public:
172
+ vector<int > assignTasks(vector<int >& servers, vector<int >& tasks) {
173
+ using pii = pair<int, int>;
174
+ using arr3 = array<int, 3>;
175
+ priority_queue<pii, vector<pii >, greater<pii >> idle;
176
+ priority_queue<arr3, vector<arr3 >, greater<arr3 >> busy;
177
+ for (int i = 0; i < servers.size(); ++i) {
178
+ idle.push({servers[ i] , i});
179
+ }
180
+ int m = tasks.size();
181
+ vector<int > ans(m);
182
+ for (int j = 0; j < m; ++j) {
183
+ int t = tasks[ j] ;
184
+ while (!busy.empty() && busy.top()[ 0] <= j) {
185
+ auto [ _ , s, i] = busy.top();
186
+ busy.pop();
187
+ idle.push({s, i});
188
+ }
189
+
190
+ if (!idle.empty()) {
191
+ auto [s, i] = idle.top();
192
+ idle.pop();
193
+ ans[j] = i;
194
+ busy.push({j + t, s, i});
195
+ } else {
196
+ auto [w, s, i] = busy.top();
197
+ busy.pop();
198
+ ans[j] = i;
199
+ busy.push({w + t, s, i});
200
+ }
201
+ }
202
+ return ans;
203
+ }
204
+ };
205
+ ```
206
+
207
+ #### Go
208
+
209
+ ``` go
210
+ func assignTasks (servers []int , tasks []int ) (ans []int ) {
211
+ idle := hp{}
212
+ busy := hp2{}
213
+ for i , x := range servers {
214
+ heap.Push (&idle, pair{x, i})
215
+ }
216
+ for j , t := range tasks {
217
+ for len (busy) > 0 && busy[0 ].w <= j {
218
+ p := heap.Pop (&busy).(tuple)
219
+ heap.Push (&idle, pair{p.s , p.i })
220
+ }
221
+ if idle.Len () > 0 {
222
+ p := heap.Pop (&idle).(pair)
223
+ ans = append (ans, p.i )
224
+ heap.Push (&busy, tuple{j + t, p.s , p.i })
225
+ } else {
226
+ p := heap.Pop (&busy).(tuple)
227
+ ans = append (ans, p.i )
228
+ heap.Push (&busy, tuple{p.w + t, p.s , p.i })
229
+ }
230
+ }
231
+ return
232
+ }
233
+
234
+ type pair struct {
235
+ s int
236
+ i int
237
+ }
238
+
239
+ type hp []pair
240
+
241
+ func (h hp ) Len () int { return len (h) }
242
+ func (h hp ) Less (i , j int ) bool {
243
+ a , b := h[i], h[j]
244
+ return a.s < b.s || a.s == b.s && a.i < b.i
245
+ }
246
+ func (h hp ) Swap (i , j int ) { h[i], h[j] = h[j], h[i] }
247
+ func (h *hp ) Push (v any ) { *h = append (*h, v.(pair)) }
248
+ func (h *hp ) Pop () any { a := *h; v := a[len (a)-1 ]; *h = a[:len (a)-1 ]; return v }
249
+
250
+ type tuple struct {
251
+ w int
252
+ s int
253
+ i int
254
+ }
255
+
256
+ type hp2 []tuple
257
+
258
+ func (h hp2 ) Len () int { return len (h) }
259
+ func (h hp2 ) Less (i , j int ) bool {
260
+ a , b := h[i], h[j]
261
+ return a.w < b.w || a.w == b.w && (a.s < b.s || a.s == b.s && a.i < b.i )
262
+ }
263
+ func (h hp2 ) Swap (i , j int ) { h[i], h[j] = h[j], h[i] }
264
+ func (h *hp2 ) Push (v any ) { *h = append (*h, v.(tuple)) }
265
+ func (h *hp2 ) Pop () any { a := *h; v := a[len (a)-1 ]; *h = a[:len (a)-1 ]; return v }
266
+ ```
267
+
268
+ #### TypeScript
269
+
270
+ ``` ts
271
+ function assignTasks(servers : number [], tasks : number []): number [] {
272
+ const idle = new PriorityQueue ({
273
+ compare : (a , b ) => (a [0 ] === b [0 ] ? a [1 ] - b [1 ] : a [0 ] - b [0 ]),
274
+ });
275
+ const busy = new PriorityQueue ({
276
+ compare : (a , b ) =>
277
+ a [0 ] === b [0 ] ? (a [1 ] === b [1 ] ? a [2 ] - b [2 ] : a [1 ] - b [1 ]) : a [0 ] - b [0 ],
278
+ });
279
+ for (let i = 0 ; i < servers .length ; ++ i ) {
280
+ idle .enqueue ([servers [i ], i ]);
281
+ }
282
+ const ans: number [] = [];
283
+ for (let j = 0 ; j < tasks .length ; ++ j ) {
284
+ const t = tasks [j ];
285
+ while (busy .size () > 0 && busy .front ()! [0 ] <= j ) {
286
+ const [_, s, i] = busy .dequeue ()! ;
287
+ idle .enqueue ([s , i ]);
288
+ }
289
+ if (idle .size () > 0 ) {
290
+ const [s, i] = idle .dequeue ()! ;
291
+ busy .enqueue ([j + t , s , i ]);
292
+ ans .push (i );
293
+ } else {
294
+ const [w, s, i] = busy .dequeue ()! ;
295
+ busy .enqueue ([w + t , s , i ]);
296
+ ans .push (i );
297
+ }
155
298
}
299
+ return ans ;
156
300
}
157
301
```
158
302
0 commit comments