@@ -79,13 +79,13 @@ tags:
7979
8080### 方法一:优先队列(小根堆)
8181
82- 定义两个优先级队列,分别表示空闲服务器、使用中的服务器。其中:空闲服务器 ` idle ` 依据 ** 权重、下标 ** 排序;而使用中的服务器 ` busy ` 依据 ** 结束时间、权重、下标 ** 排序 。
82+ 我们用一个小根堆 $\textit{ idle}$ 来维护所有的空闲服务器,其中每个元素是一个二元组 $(x, i)$,表示第 $i$ 台服务器的权重为 $x$。用一个小根堆 $\textit{ busy}$ 来维护所有的忙碌服务器,其中每个元素是一个三元组 $(w, s, i)$,表示第 $i$ 台服务器在第 $w$ 秒恢复空闲,权重为 $s$。初始时我们将所有的服务器加入到 $\textit{idle}$ 中 。
8383
84- 遍历任务:
84+ 接下来,我们遍历所有的任务,对于第 $j$ 项任务,我们首先将所有在第 $j$ 秒或之前恢复空闲的服务器从 $\textit{busy}$ 中移除,添加到 $\textit{idle}$ 中。然后我们从 $\textit{idle}$ 中取出一个权重最小的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。如果 $\textit{idle}$ 为空,我们从 $\textit{busy}$ 中取出一个恢复时间最早的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。
8585
86- - 若有使用中的服务器小于任务开始时间,将其加入到空闲服务器队列 ` idle ` 中;
87- - 若当前有空闲服务器,那么在空闲队列 ` idle ` 中取出权重最小的服务器,将其加入使用中的队列 ` busy ` 中;
88- - 若当前没有空闲服务器,那么在使用队列 ` busy ` 中找出最早结束时间且权重最小的服务器,重新加入使用中的队列 ` busy ` 中 。
86+ 遍历结束后,我们得到了答案数组 $\textit{ans}$。
87+
88+ 时间复杂度 $O((n + m) \log n)$,其中 $n$ 为服务器的数量,$m$ 为任务的数量。空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为服务器和任务的数量 。
8989
9090相似题目:
9191
@@ -98,61 +98,205 @@ tags:
9898``` python
9999class Solution :
100100 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 :
107107 _, s, i = heappop(busy)
108108 heappush(idle, (s, i))
109109 if idle:
110110 s, i = heappop(idle)
111- heappush(busy, (start + cost , s, i))
111+ heappush(busy, (j + t , s, i))
112112 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
117117```
118118
119119#### Java
120120
121121``` java
122122class Solution {
123123 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+ });
127131 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 ];
130134 }
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 ];
132139 });
133- for (int i = 0 ; i < n; ++ i ) {
140+ for (int i = 0 ; i < n; i ++ ) {
134141 idle. offer(new int [] {servers[i], i});
135142 }
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 ]});
143150 }
144151 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 });
148155 } 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});
152160 }
153161 }
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+ }
155298 }
299+ return ans ;
156300}
157301```
158302
0 commit comments