TreeSet及优先队列的操作

这一题,用普通方法会暴力超时,所以采用优先队列及TreeSet进行排序,减少复杂度,在此记录一下优先队列,treeset的一些使用技巧 

答案如下 

class Solution {
    public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
        //统计处理任务数
        int[] cnts = new int[k]; 
        Arrays.fill(cnts, 0);
        int n = arrival.length, max = 0;
        // Map<Integer, Integer> map = new HashMap<>();
        //优先队列存储当前忙碌的服务器索引及其任务结束时间,根据结束时间升序排列
        PriorityQueue<int[]> busy = new PriorityQueue<>((a,b)->a[1]-b[1]);
        //红黑树集合 存储当前任务开始时刻,所有空闲的服务器索引
        TreeSet<Integer> free = new TreeSet<>();
        //初始所有服务器均空闲,全部加入到free
        for (int i = 0; i < k; i++) free.add(i);
        //依次遍历每一个任务
        for (int i = 0; i < n; i++) {
            //当前待分配任务的开始时刻与结束时刻
            int start = arrival[i], end = start + load[i];
            //找出所有当前忙碌的服务器的任务结束时刻早于待分配任务的开始时刻的,都加入到free集合中等待筛选
            while (!busy.isEmpty() && busy.peek()[1] <= start) free.add(busy.poll()[0]);
            //用u来表示当前轮次待分配到的服务器索引,优先取 >= i%k的
            Integer u = free.ceiling(i % k);
            //若取不到,则取>=0的
            if (u == null) u = free.ceiling(0);
            //若依然取不到,则放弃该任务
            if (u == null) continue;
            //取到了,将该服务器索引从free中移除
            free.remove(u);
            //与此同时,将该服务器加入到忙碌队列中,存储一个长度为2的数组,[0]:索引 [1]:任务结束时刻
            busy.add(new int[]{u, end});
            //更新当前最大的处理任务数目
            max = Math.max(max, ++cnts[u]);
        }
        //将最忙碌的服务器索引筛选出来加入List
        List<Integer> ans = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            if (cnts[i] == max) ans.add(i);
        }
        return ans;
    }
}

 优先队列自定义排序,优先队列里面放数组,按照数组的第二个元素大小进行升序排列

        //优先队列存储当前忙碌的服务器索引及其任务结束时间,根据结束时间升序排列
        PriorityQueue<int[]> busy = new PriorityQueue<>((a,b)->a[1]-b[1]);

TreeSet 默认对元素进行升序排序,TreeSet.ceiling(i),指优先取>=i的 

  //用u来表示当前轮次待分配到的服务器索引,优先取 >= i%k的
            Integer u = free.ceiling(i % k);

去网站外搜索优先队列和TreeSet的其他用法

优先队列

//摘自ocjp:
import java.util.*;
public class GetInLine {
	public static void main(String[] args) {
		PriorityQueue<String> pq = new PriorityQueue<String>();
		pq.add("banana");
		pq.add("pear");
		pq.add("apple");
		System.out.println(pq.poll() + " " + pq.peek());
	}
}
What is the result?
A. apple pear
B. banana pear
C. apple apple
D. apple banana
E. banana banana
Answer: D

poll()是取得头节点,然后从队列中删除。
peek()是取得头节点。
clear()是删除所有节点。
iterator()是返回一个循环iterator
remove(Object o)是从队列中删除对象o

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值