leetcode
leetcode 2351 ~ 2400
统计没有收到请求的服务器数目

统计没有收到请求的服务器数目

难度:

标签:

题目描述

You are given an integer n denoting the total number of servers and a 2D 0-indexed integer array logs, where logs[i] = [server_id, time] denotes that the server with id server_id received a request at time time.

You are also given an integer x and a 0-indexed integer array queries.

Return a 0-indexed integer array arr of length queries.length where arr[i] represents the number of servers that did not receive any requests during the time interval [queries[i] - x, queries[i]].

Note that the time intervals are inclusive.

 

Example 1:

Input: n = 3, logs = [[1,3],[2,6],[1,5]], x = 5, queries = [10,11]
Output: [1,2]
Explanation: 
For queries[0]: The servers with ids 1 and 2 get requests in the duration of [5, 10]. Hence, only server 3 gets zero requests.
For queries[1]: Only the server with id 2 gets a request in duration of [6,11]. Hence, the servers with ids 1 and 3 are the only servers that do not receive any requests during that time period.

Example 2:

Input: n = 3, logs = [[2,4],[2,1],[1,2],[3,1]], x = 2, queries = [3,4]
Output: [0,1]
Explanation: 
For queries[0]: All servers get at least one request in the duration of [1, 3].
For queries[1]: Only server with id 3 gets no request in the duration [2,4].

 

Constraints:

  • 1 <= n <= 105
  • 1 <= logs.length <= 105
  • 1 <= queries.length <= 105
  • logs[i].length == 2
  • 1 <= logs[i][0] <= n
  • 1 <= logs[i][1] <= 106
  • 1 <= x <= 105
  • x < queries[i] <= 106

代码结果

运行时间: 214 ms, 内存: 64.2 MB


/* 
 思路: 
 1. 使用Java Stream API和集合操作来优化。 
 2. 创建一个Map来保存每个服务器的最后请求时间。 
 3. 遍历查询数组,对每个查询,在相应的时间区间内检查每个服务器是否收到请求。 
 4. 使用流操作来计算没有收到请求的服务器数量。 
 */ 

 import java.util.*; 
 import java.util.stream.*; 

 public class ServerRequestsStream { 

     public int[] countServers(int n, int[][] logs, int x, int[] queries) { 
         Map<Integer, Integer> lastRequestTime = Arrays.stream(logs) 
             .collect(Collectors.toMap(log -> log[0], log -> log[1], Math::max)); 

         return Arrays.stream(queries) 
             .map(query -> { 
                 int startTime = query - x; 
                 return (int) IntStream.rangeClosed(1, n) 
                     .filter(serverId -> lastRequestTime.getOrDefault(serverId, -1) < startTime) 
                     .count(); 
             }).toArray(); 
     } 

     public static void main(String[] args) { 
         ServerRequestsStream sr = new ServerRequestsStream(); 
         int n = 3; 
         int[][] logs = {{1, 3}, {2, 6}, {1, 5}}; 
         int x = 5; 
         int[] queries = {10, 11}; 
         System.out.println(Arrays.toString(sr.countServers(n, logs, x, queries))); 
     } 
 }

解释

方法:

本题解采用滑动窗口方法配合双指针技术,对日志进行分析以找出没有收到请求的服务器数。首先,日志按时间进行排序,以便使用双指针滑动窗口来维护时间区间。然后,对查询也进行排序,以便同步处理。在处理过程中,我们维护一个数组cnt,记录每个服务器在当前查询时间窗口内的请求数。同时,用out_of_range记录当前时间窗口内没有收到请求的服务器数量。通过逐步移动两个指针(left和right)来更新这些统计数据——当右指针向右移动时,扩展窗口;当左指针向右移动时,缩小窗口。最终,每次查询的结果即为out_of_range的值。

时间复杂度:

O(m log m + q log q + m)

空间复杂度:

O(n + q)

代码细节讲解

🦆
双指针技术在这个问题中是如何具体应用的?能否详细解释左右指针各自的移动条件和移动时对问题解决的贡献?
在本题中,双指针技术用于维护一个时间窗口,该窗口内的日志表示在当前查询时间内服务器接收到的请求。左指针和右指针分别表示窗口的开始和结束。右指针向右移动时,扩展窗口以包括所有不超过当前查询时间的请求,增加相应服务器的请求计数,并适当调整没有收到请求的服务器数量。当服务器从未收到请求到收到请求时,该服务器不再被计入未收到请求的服务器数,因此需要减少out_of_range的值。左指针向右移动时,缩小窗口以排除早于当前查询时间窗口的请求,减少相应服务器的请求计数,并适当调整没有收到请求的服务器数量。当服务器的请求计数重新变为零时,意味着它在当前查询窗口内没有任何请求,因此需要增加out_of_range的值。这种双指针的运用确保了我们能够有效地根据时间窗口更新每个服务器的请求状态,从而在每次查询时都能准确计算出未收到请求的服务器数量。
🦆
在更新服务器的请求计数(cnt数组)时,为什么在cnt[i]为0时减少out_of_range,而在cnt[i]变回0时又增加out_of_range?这种处理方式有什么特别的意义?
数组cnt用于记录每个服务器在当前查询时间窗口内的请求计数。当cnt[i]为0时表示该服务器在当前窗口内尚未收到任何请求,因此是计入out_of_range的一个。如果此时这个服务器接收到了一个请求,其cnt[i]从0变为1,因此需要从out_of_range中减去这个服务器,因为它不再是未收到请求的服务器。相反,当一个服务器在时间窗口调整后(左指针移动)其请求计数重新变为0,说明它在新的时间窗口内没有收到任何请求,因此需要重新将这个服务器计入out_of_range。这种处理确保out_of_range始终准确反映当前查询时间窗口内未收到请求的服务器总数。
🦆
如果在查询期间日志数据非常密集,这种双指针滑动窗口方法的效率如何?会不会有性能瓶颈?
当日志数据非常密集时,右指针可能频繁向右移动,而每次移动都需要更新服务器的请求计数和out_of_range值。虽然这种情况下双指针方法可能会有较高的运算量,但整体效率仍然相对较高,因为每个日志只被处理两次(一次由右指针处理,一次由左指针处理),因此时间复杂度为O(m + q),其中m是日志条数,q是查询次数。然而,在极端情况下,例如日志非常密集且服务器数量很大时,频繁更新cnt数组和计算out_of_range可能会导致性能瓶颈。在这种情况下,可能需要考虑更高效的数据结构或优化算法来进一步提升性能。

相关问题