1606. 找到处理最多请求的服务器【困难题】【每日一题】
思路:
使用优先队列 + TreeSet 进行模拟,阅读官方题解之后对代码注释如下。
代码:
class Solution {
public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
TreeSet<Integer> available = new TreeSet<>();//定义available有序集合,存放空闲服务器的编号
for (int i = 0; i < k; i++) {//初始状态所有的服务器均空闲,将所有服务器编号都添加进available
available.add(i);
}
//定义优先队列 busy,存储正在处理请求的服务器编号以及它们对应的处理结束时间,队首的处理结束时间最小
//busy中存储 int[] 长度为2 [0]表示处理结束时间,[1]表示服务器编号
PriorityQueue<int[]> busy = new PriorityQueue<>((a,b)->a[0]-b[0]);
int[] requests = new int[k];//定义request数组记录每一台服务器处理的请求数目
int len = arrival.length;
for (int i = 0; i < len; i++) {
//当busy不为空,且busy中最适合处理请求的处理器的结束时间小于等于当前请求的到达时间
while (!busy.isEmpty() && busy.peek()[0] <= arrival[i]){
//此时可以从busy取出队首的服务器,将它取出并放入available集合中,表示该服务器进入就绪状态
available.add(busy.poll()[1]);
}
//如果available为空,说明当前没有空闲的服务器处理当前请求,根据题目规则,此时应该将当前请求丢弃
if (available.isEmpty()){
//丢弃当前请求,判断下一次请求
continue;
}
//如果有空闲服务器处理当前请求,那么根据题意,此时应该判断第 i % k 个服务器是否空闲,如果是那么令这个服务器处理当前请求
//于是在available中寻找第一个 大于等于 i % k 的服务器,将目标服务器编号设为 p
Integer p = available.ceiling(i % k);
//如果 p 为空,说明在available中没有找到目标服务器,那么根据题意,此时应该将请求交给第一个空闲的服务器处理
if (p == null){
//将目标服务器编号 p = available中第一个元素
p = available.first();
}
//处理当前请求的服务器编号为 p,处理一次请求,对应在request数组中+1
requests[p]++;
// p 服务器开始处理请求,将其添加到busy队列,处理结束时间为 当前请求的到达时间+处理请求所需时间
busy.offer(new int[]{arrival[i]+load[i],p});
// p 服务器开始处理请求,将其从 available 就绪列表中移除
available.remove(p);
}
//使用Arrays.stream求request数组中的最大值 max
int max = Arrays.stream(requests).max().getAsInt();
//定义列表ans用来存储最繁忙服务器的序号
List<Integer> ans = new ArrayList<>();
//遍历request数组,只要等于max,就将其编号i存入ans列表
for (int i = 0; i < k; i++) {
if (requests[i] == max){
ans.add(i);
}
}
//返回ans
return ans;
}
}
204. 计数质数【中等题】
思路:【题解埃氏筛】
- 定义状态数组status,元素为0表示不是合数,元素为1表示是合数。
- 从最小的质数开始遍历,到n-1结束,遍历到的数字为i,判断i位置的status状态值,如果是0,表示这个数是质数,那么首先ans++,然后从这个数的平方倍开始(如果这个数的平方还小于n的话),从i的平方开始,逐次累加i,将遍历到的每个j位置的status状态值置为1表示这些数全是合数,不用统计;如果i位置的status状态是是1,说明当前i是合数,不用判断,继续去找下一个数。
- 上述外层循环中,如果遍历到的数是质数,那么就ans++,因此ans即为小于n的所有质数的个数,返回ans即可。
代码:
class Solution {
public int countPrimes(int n) {
int[] status = new int[n];
int ans = 0;
for (int i = 2; i < n; i++) {
if (status[i] == 0){
ans++;
if ((long) i*i < n){
for (int j = i*i; j < n; j+=i) {
status[j] = 1;
}
}
}
}
return ans;
}
}