当前位置:   article > 正文

数据结构中的堆

数据结构中的堆

优先队列是队列数据结构实现,其中根据优先级处理对象,在优先队列中,添加的对象根据其优先级,默认情况下,优先级由对象的自然顺序决定的。队列构建时提供的比较器可以覆盖默认优先级。

优先队列就是一个堆,它可以维护一个集合的最大值(或最小值),可以在很优秀的时间复杂度(log级别)内进行查询,插入push和删除pop.

例题

问题描述

小雷拿到了一个数组,他计算了一下数组的和,感觉和也太大了,所以他准备对数组中的每个元素进行取余操作,让数组的和变得小一点。

具体来说,给定一个数组 a ,共有 q 次操作,每次操作给定一个值 x ,对数组的每个元素对 x 进行一次取模,输出每次操作后,数组所有元素的和。

输入格式

第一行有两个整数n,q ,代表数组 a 的元素个数和操作个数。

第二行输入 n 个元素,代表数组 a 。

第三行输入 q 个元素,代表 q 次操作。

输出格式

输出仅一行,包含 q 个由空格分开的整数,第 i 个整数代表第 qi​ 次操作后的结果。

样例输入

  1. 5 3
  2. 1 2 3 4 5
  3. 4 2 1

样例输出 

7 3 0

说明 

初始数组为 [1,2,3,4,5] ,和为 15 。

进行第一次 x 为 4 的取模操作后,数组变为 [1,2,3,0,1] ,和为 7 。

进行第二次 x 为 2 的取模操作后,数组变为 [1,0,1,0,1] ,和为 3 。

进行第三次 x 为 1 的取模操作后,数组变为 [0,0,0,0,0] ,和为 0。

构建数值从大到小的优先序列

每次比较对头和x的大小关系,如果队头大于x,把对头弹出来,将队头对x取模的值压入队列中。

代码

  1. package dui;
  2. import java.util.*;
  3. public class chapter1 {
  4. public static void main(String[] args) {
  5. // TODO Auto-generated method stub
  6. Scanner scan=new Scanner(System.in);
  7. int n=scan.nextInt();
  8. int q=scan.nextInt();
  9. long sum=0;
  10. PriorityQueue<Integer> queue=new PriorityQueue<>((o1,o2)->o2-o1);
  11. for(int i=0;i<n;i++) {
  12. int x=scan.nextInt();
  13. queue.add(x);
  14. sum+=x;
  15. }
  16. while(q-->0) {
  17. //q次操作
  18. int k=scan.nextInt();
  19. while(!queue.isEmpty()&&queue.peek()>=k) {
  20. //判断队列是否为空,以及对头中的元素大于我们当前要取余的值
  21. int x=queue.poll();//弹出(一直弹出比k大的数)
  22. sum-=x;
  23. queue.add(x%k);//对k取余后的值添加到队列中
  24. sum+=x%k;
  25. }
  26. System.out.print(sum+" ");//每次需要输出sum
  27. }
  28. }
  29. }

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/386390
推荐阅读
相关标签
  

闽ICP备14008679号