LeetCode每日一题(1606. Find Servers That Handled Most Number of Requests)

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()
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值