Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9953fd3

Browse files
authored
feat: add solutions to lc problem: No.1882 (doocs#4047)
No.1882.Process Tasks Using Servers
1 parent 05543d9 commit 9953fd3

File tree

7 files changed

+535
-106
lines changed

7 files changed

+535
-106
lines changed

solution/1800-1899/1882.Process Tasks Using Servers/README.md

Lines changed: 181 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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
9999
class 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
122122
class 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

Comments
 (0)