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

feat: add solutions to lc problem: No.1882 #4047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 181 additions & 37 deletions solution/1800-1899/1882.Process Tasks Using Servers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ tags:

### 方法一:优先队列(小根堆)

定义两个优先级队列,分别表示空闲服务器、使用中的服务器。其中:空闲服务器 `idle` 依据**权重、下标**排序;而使用中的服务器 `busy` 依据**结束时间、权重、下标**排序
我们用一个小根堆 $\textit{idle}$ 来维护所有的空闲服务器,其中每个元素是一个二元组 $(x, i)$,表示第 $i$ 台服务器的权重为 $x$。用一个小根堆 $\textit{busy}$ 来维护所有的忙碌服务器,其中每个元素是一个三元组 $(w, s, i)$,表示第 $i$ 台服务器在第 $w$ 秒恢复空闲,权重为 $s$。初始时我们将所有的服务器加入到 $\textit{idle}$ 中

遍历任务:
接下来,我们遍历所有的任务,对于第 $j$ 项任务,我们首先将所有在第 $j$ 秒或之前恢复空闲的服务器从 $\textit{busy}$ 中移除,添加到 $\textit{idle}$ 中。然后我们从 $\textit{idle}$ 中取出一个权重最小的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。如果 $\textit{idle}$ 为空,我们从 $\textit{busy}$ 中取出一个恢复时间最早的服务器,将其加入到 $\textit{busy}$ 中,处理第 $j$ 项任务。

- 若有使用中的服务器小于任务开始时间,将其加入到空闲服务器队列 `idle` 中;
- 若当前有空闲服务器,那么在空闲队列 `idle` 中取出权重最小的服务器,将其加入使用中的队列 `busy` 中;
- 若当前没有空闲服务器,那么在使用队列 `busy` 中找出最早结束时间且权重最小的服务器,重新加入使用中的队列 `busy` 中
遍历结束后,我们得到了答案数组 $\textit{ans}$。

时间复杂度 $O((n + m) \log n)$,其中 $n$ 为服务器的数量,$m$ 为任务的数量。空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为服务器和任务的数量

相似题目:

Expand All @@ -98,61 +98,205 @@ tags:
```python
class Solution:
def assignTasks(self, servers: List[int], tasks: List[int]) -> List[int]:
idle, busy = [], []
for i, weight in enumerate(servers):
heappush(idle, (weight, i))
res = []
for start, cost in enumerate(tasks):
while busy and busy[0][0] <= start:
idle = [(x, i) for i, x in enumerate(servers)]
heapify(idle)
busy = []
ans = []
for j, t in enumerate(tasks):
while busy and busy[0][0] <= j:
_, s, i = heappop(busy)
heappush(idle, (s, i))
if idle:
s, i = heappop(idle)
heappush(busy, (start + cost, s, i))
heappush(busy, (j + t, s, i))
else:
t, s, i = heappop(busy)
heappush(busy, (t + cost, s, i))
res.append(i)
return res
w, s, i = heappop(busy)
heappush(busy, (w + t, s, i))
ans.append(i)
return ans
```

#### Java

```java
class Solution {
public int[] assignTasks(int[] servers, int[] tasks) {
int m = tasks.length, n = servers.length;
PriorityQueue<int[]> idle
= new PriorityQueue<>((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
int n = servers.length;
PriorityQueue<int[]> idle = new PriorityQueue<>((a, b) -> {
if (a[0] != b[0]) {
return a[0] - b[0];
}
return a[1] - b[1];
});
PriorityQueue<int[]> busy = new PriorityQueue<>((a, b) -> {
if (a[0] == b[0]) {
return a[1] == b[1] ? a[2] - b[2] : a[1] - b[1];
if (a[0] != b[0]) {
return a[0] - b[0];
}
return a[0] - b[0];
if (a[1] != b[1]) {
return a[1] - b[1];
}
return a[2] - b[2];
});
for (int i = 0; i < n; ++i) {
for (int i = 0; i < n; i++) {
idle.offer(new int[] {servers[i], i});
}
int[] res = new int[m];
int j = 0;
for (int start = 0; start < m; ++start) {
int cost = tasks[start];
while (!busy.isEmpty() && busy.peek()[0] <= start) {
int[] item = busy.poll();
idle.offer(new int[] {item[1], item[2]});
int m = tasks.length;
int[] ans = new int[m];
for (int j = 0; j < m; ++j) {
int t = tasks[j];
while (!busy.isEmpty() && busy.peek()[0] <= j) {
int[] p = busy.poll();
idle.offer(new int[] {p[1], p[2]});
}
if (!idle.isEmpty()) {
int[] item = idle.poll();
res[j++] = item[1];
busy.offer(new int[] {start + cost, item[0], item[1]});
int i = idle.poll()[1];
ans[j] = i;
busy.offer(new int[] {j + t, servers[i], i});
} else {
int[] item = busy.poll();
res[j++] = item[2];
busy.offer(new int[] {item[0] + cost, item[1], item[2]});
int[] p = busy.poll();
int i = p[2];
ans[j] = i;
busy.offer(new int[] {p[0] + t, p[1], i});
}
}
return res;
return ans;
}
}
```

#### C++

```cpp
class Solution {
public:
vector<int> assignTasks(vector<int>& servers, vector<int>& tasks) {
using pii = pair<int, int>;
using arr3 = array<int, 3>;
priority_queue<pii, vector<pii>, greater<pii>> idle;
priority_queue<arr3, vector<arr3>, greater<arr3>> busy;
for (int i = 0; i < servers.size(); ++i) {
idle.push({servers[i], i});
}
int m = tasks.size();
vector<int> ans(m);
for (int j = 0; j < m; ++j) {
int t = tasks[j];
while (!busy.empty() && busy.top()[0] <= j) {
auto [_, s, i] = busy.top();
busy.pop();
idle.push({s, i});
}

if (!idle.empty()) {
auto [s, i] = idle.top();
idle.pop();
ans[j] = i;
busy.push({j + t, s, i});
} else {
auto [w, s, i] = busy.top();
busy.pop();
ans[j] = i;
busy.push({w + t, s, i});
}
}
return ans;
}
};
```

#### Go

```go
func assignTasks(servers []int, tasks []int) (ans []int) {
idle := hp{}
busy := hp2{}
for i, x := range servers {
heap.Push(&idle, pair{x, i})
}
for j, t := range tasks {
for len(busy) > 0 && busy[0].w <= j {
p := heap.Pop(&busy).(tuple)
heap.Push(&idle, pair{p.s, p.i})
}
if idle.Len() > 0 {
p := heap.Pop(&idle).(pair)
ans = append(ans, p.i)
heap.Push(&busy, tuple{j + t, p.s, p.i})
} else {
p := heap.Pop(&busy).(tuple)
ans = append(ans, p.i)
heap.Push(&busy, tuple{p.w + t, p.s, p.i})
}
}
return
}

type pair struct {
s int
i int
}

type hp []pair

func (h hp) Len() int { return len(h) }
func (h hp) Less(i, j int) bool {
a, b := h[i], h[j]
return a.s < b.s || a.s == b.s && a.i < b.i
}
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

type tuple struct {
w int
s int
i int
}

type hp2 []tuple

func (h hp2) Len() int { return len(h) }
func (h hp2) Less(i, j int) bool {
a, b := h[i], h[j]
return a.w < b.w || a.w == b.w && (a.s < b.s || a.s == b.s && a.i < b.i)
}
func (h hp2) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *hp2) Push(v any) { *h = append(*h, v.(tuple)) }
func (h *hp2) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
```

#### TypeScript

```ts
function assignTasks(servers: number[], tasks: number[]): number[] {
const idle = new PriorityQueue({
compare: (a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]),
});
const busy = new PriorityQueue({
compare: (a, b) =>
a[0] === b[0] ? (a[1] === b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0],
});
for (let i = 0; i < servers.length; ++i) {
idle.enqueue([servers[i], i]);
}
const ans: number[] = [];
for (let j = 0; j < tasks.length; ++j) {
const t = tasks[j];
while (busy.size() > 0 && busy.front()![0] <= j) {
const [_, s, i] = busy.dequeue()!;
idle.enqueue([s, i]);
}
if (idle.size() > 0) {
const [s, i] = idle.dequeue()!;
busy.enqueue([j + t, s, i]);
ans.push(i);
} else {
const [w, s, i] = busy.dequeue()!;
busy.enqueue([w + t, s, i]);
ans.push(i);
}
}
return ans;
}
```

Expand Down
Loading