You have k servers numbered from 0 to k-1 that are being used to handle multiple requests simultaneously. Each server has infinite computational capacity but cannot handle more than one request at a time. The requests are assigned to servers according to a specific algorithm:
The ith (0-indexed) request arrives.
If all servers are busy, the request is dropped (not handled at all).
If the (i % k)th server is available, assign the request to that server.
Otherwise, assign the request to the next available server (wrapping around the list of servers and starting from 0 if necessary). For example, if the ith server is busy, try to assign the request to the (i+1)th server, then the (i+2)th server, and so on.
You are given a strictly increasing array arrival of positive integers, where arrival[i] represents the arrival time of the ith request, and another array load, where load[i] represents the load of the ith request (the time it takes to complete). Your goal is to find the busiest server(s). A server is considered busiest if it handled the most number of requests successfully among all the servers.
Return a list containing the IDs (0-indexed) of the busiest server(s). You may return the IDs in any order.
Example 1:
Input: k = 3, arrival = [1,2,3,4,5], load = [5,2,3,3,3]
Output: [1]
Explanation:
All of the servers start out available.
The first 3 requests are handled by the first 3 servers in order.
Request 3 comes in. Server 0 is busy, so it’s assigned to the next available server, which is 1.
Request 4 comes in. It cannot be handled since all servers are busy, so it is dropped.
Servers 0 and 2 handled one request each, while server 1 handled two requests. Hence server 1 is the busiest server.
Example 2:
Input: k = 3, arrival = [1,2,3,4], load = [1,2,1,2]
Output: [0]
Explanation:
The first 3 requests are handled by first 3 servers.
Request 3 comes in. It is handled by server 0 since the server is available.
Server 0 handled two requests, while servers 1 and 2 handled one request each. Hence server 0 is the busiest server.
Example 3:
Input: k = 3, arrival = [1,2,3], load = [10,12,11]
Output: [0,1,2]
Explanation: Each server handles a single request, so they are all considered the busiest.
Constraints:
- 1 <= k <= 105
- 1 <= arrival.length, load.length <= 105
- arrival.length == load.length
- 1 <= arrival[i], load[i] <= 109
- arrival is strictly increasing.
用一个数组(idle_servers)来保存空闲的 server number, 其中的 server number 正序排列。
再用一个 min binary heap(busy_servers)来保存处于工作状态的 server 的结束时间和 server number。
遍历 arrival, 将 busy_servers 中所有小于 request 开始时间的 server 都取出然后通过二分搜索法在 idle_servers 中查找插入位置进行插入。然后再通过二分搜索法搜索目标 server number 即 index_of_request % k, 将找到的 server number 从 idle_servers 中移除, 然后将结束时间(start_time + load[index_of_request])和 server number 放到 busy_servers 中
use std::cmp::Reverse;
use std::collections::BinaryHeap;
impl Solution {
pub fn busiest_servers(k: i32, arrival: Vec<i32>, load: Vec<i32>) -> Vec<i32> {
let mut idle_servers: Vec<i32> = (0..k).into_iter().collect();
let mut scores = vec![0; k as usize];
let mut busy_servers: BinaryHeap<Reverse<(i32, i32)>> = BinaryHeap::new();
for (i, start) in arrival.into_iter().enumerate() {
let target_server = i as i32 % k;
while let Some(Reverse((end, server))) = busy_servers.pop() {
if end > start {
busy_servers.push(Reverse((end, server)));
break;
}
let idx = idle_servers.binary_search(&server).unwrap_err();
idle_servers.insert(idx, server);
}
if idle_servers.is_empty() {
continue;
}
match idle_servers.binary_search(&target_server) {
Ok(idx) => {
idle_servers.remove(idx);
busy_servers.push(Reverse((start + load[i], target_server)));
scores[target_server as usize] += 1;
}
Err(idx) => {
let server;
if idx == idle_servers.len() as usize {
server = idle_servers.remove(0);
} else {
server = idle_servers.remove(idx);
}
busy_servers.push(Reverse((start + load[i], server)));
scores[server as usize] += 1;
}
}
}
let max_score = *scores.iter().max().unwrap();
scores
.into_iter()
.enumerate()
.filter(|&(_, v)| v == max_score)
.map(|(i, _)| i as i32)
.collect()
}
}