【华为OD题库-038】支持优先级的对列-java

题目

实现一个支持优先级的队列,高优先级先出队列,同优先级时先进先出。
如果两个输入数据和优先级都相同,则后一个数据不入队列被丢弃。
队列存储的数据内容是一个 整数。
输入描述
一组待存入队列的数据(包含内容和优先级)。
输出描述
队列的数据内容(优先级信息输出时不再体现)。
补充说明
不用考虑数据不合法的情况,测试数据不超过100个。
示例1
输入:
(10,1),(20,1).(30,2).(40,3)
输出:
40,30,10,20
说明:
输入样例中,向队列写入了4个数据,每个数据由数据内容和优先级组成。输入和输出内容都不含空格。数据40的优先级最高,所以最先输出,其次是30;10和20优先级相同,所以按输入顺序输出
示例2
输入:
(10,1),(10,1).(30,2).(40,3)
输出:
40,30,10
说明:
输入样例中,向队列写入了4个数据,每个数据由数据内容和优先级组成输入和输出内容都不含空格。
数据40的优先级最高,所以最先输出,其次是30;两个10和10构成重复数据,被丢弃一个。

思路

基础的数据结构题,大概三个思路:

  1. 直接放入list,转对象排序,可以实现要求
  2. 使用内置的PriorityQueue对象实现
  3. 自定义数据结构实现

猜测考察点在第三点,不然前两个虽然能达到目的,但是没有意义

排序实现

分析题目,排序规则为:

  1. 优先级高的先出,
  2. 同优先级时位置靠前的先出;
  3. 数据和优先级均相同的去重

基于以上分析,可以采用以下步骤实现:

  1. 新建一个data对象,含有priority,val,idx三个属性,idx代表出现位置
  2. 把输入转为data对象放入list中
  3. 先去重(利用HashSet),根据priority,val判重,重写equals方法
  4. 自定义排序规则,priority降序,idx升序排列。Data实现Comparable接口,重写compareTo方法

PriorityQueue实现

还是一样,新建Data对象,重写equals(去重用)和compareTo(排序用)方法
把输入转为Data对象后,直接加入PriorityQueue中
重复对象都加入到了PriorityQueue,在输出时,因为结果已经按照自定义排序规则写好了,所以去重逻辑就是当前项等于上一项时,代表重复,此时不输出对应结果即可

自定义数据结构实现

可以用两个栈实现优先级队列
stackA:优先级高的在栈顶,存放较小优先级
stackB:优先级低的在栈顶,存放较大优先级,也就是说在stackB中的优先级始终比stackA的优先级大,比如某个状态如下:
在这里插入图片描述
最后再输出结果时,只需要把stackB依次出栈再入stackA栈,再输出stackA的栈顶元素即可得到:6,5,4,3,2,1。即按优先级降序排列。
具体存放数据逻辑如下,以20 10 30 40 50为例:

  1. 存入20,首先判断它是较大优先级还是较小优先级?我们可以和stackB的栈顶元素比较(当然和stackA的栈顶元素比较也可以)。如果cur<stackB.peek()。说明是一个比stackB最低优先级还要小的元素,所以它是一个较小优先级,应该存入stackA中。此处stackB为空,没有栈顶元素,我们也先出入stackA中,由于stackA没有数据,直接存入,如下:
    在这里插入图片描述

  2. 存入10,stackB为空,所以还是存入stackA中,但是此时stackA有数据,由于定义的stackA要将较大优先级放入栈顶,即当前元素如果比stackA的栈顶元素还要小(cur<stackA.peek())时,应该把大于当前优先级的数据转入stackB
    在这里插入图片描述

  3. 存入30,大于stackB的栈顶元素,此时应该存入stackB,同样的逻辑,这里stackB是将优先级小的放入栈顶,所以cur>stackB.peek()时,应该把小于当前优先级的数据转入stackA
    在这里插入图片描述

  4. 存入40,大于stackB栈顶元素,存入stackB,将stackB小于当前优先级的元素放入stackA中
    在这里插入图片描述

  5. 存入50,大于stackB栈顶元素,存入stackB,将stackB小于当前优先级的元素放入stackA中
    在这里插入图片描述

  6. 最后输出结果,需要将stackB中的全部数据转入stackA,再依次从stackA栈顶取数据得到:50 40 30 20 10

上面的过程没有考虑优先级相同和去重时的处理逻辑,现在分析如下:

  1. 优先级相同,比如在上面的数据中再加入一个30,30小于stackB的栈顶元素,所以应该放入stackA中,将stackA大于30的元素全部弹出来:
    在这里插入图片描述
    关键在于等于30是否弹出?如果弹出,那么我们将第二个30加入到了stackA的栈顶,第一个30弹入了stackB的栈顶,最后输出结果时,一定是先输出的第一个30。符合题意,否则的话,会先输出第二个30。所以在stackA入栈时,判断条件是:cur<=stackA.peek()
    假设最后加入的不是30而是50,此时弹出到stackA时,不应该取等,即cur>stackB.peek(),即只弹出比stackB栈顶元素还大的值
    在这里插入图片描述
    如上,因为栈顶和50相等,不弹出stackA,直接加入,最后的结果一定是第一个50先输出来。

  2. 去重,根据第一点,优先级相同时的处理逻辑可以发现,当优先级相同时,始终会把之前的数据放入到stackB中去,所以我们再向stackA或者stackB加入数据时,只要判断其不等于stackB的栈顶元素即可(相等判断逻辑为优先级和值同时相同,重写equals方法实现)

题解

三种方法都定义了实体Data:

class Data implements Comparable<Data> {private int priority;private int val;private int idx;public Data(int priority, int val, int idx) {this.priority = priority;this.val = val;this.idx = idx;}public int getIdx() {return idx;}public void setIdx(int idx) {this.idx = idx;}public int getPriority() {return priority;}public void setPriority(int priority) {this.priority = priority;}public int getVal() {return val;}public void setVal(int val) {this.val = val;}public Data(int priority, int val) {this.priority = priority;this.val = val;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Data data = (Data) o;return priority == data.priority &&val == data.val;}@Overridepublic int hashCode() {return Objects.hash(priority, val);}@Overridepublic int compareTo(Data o) {if (this.priority != o.priority) return o.priority - this.priority;return this.idx - o.idx;}
}

排序实现

package hwod;import java.util.*;
import java.util.stream.Collectors;public class MyPriorityQueue {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String inputs = sc.nextLine();System.out.println(myPriorityQueue(inputs));}/*** 直接排序输出** @param str* @return*/private static String myPriorityQueue(String str) {//将输入解析为自定义对象DataSet<Data> set = new HashSet<>();String[] arrs = str.substring(1, str.length() - 1).split("\\),\\(");for (int i = 0; i < arrs.length; i++) {String[] cur = arrs[i].split(",");set.add(new Data(Integer.parseInt(cur[1]), Integer.parseInt(cur[0]), i));}List<Data> list = set.stream().sorted().collect(Collectors.toList());StringBuilder sb = new StringBuilder();for (int i = 0; i < list.size(); i++) {if (i != 0) sb.append(",");sb.append(list.get(i).getVal());}return sb.toString();}
}

PriorityQueue实现

package hwod;import java.util.*;
import java.util.stream.Collectors;public class MyPriorityQueue {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String inputs = sc.nextLine();System.out.println(myPriorityQueue(inputs));}/*** 使用java自带的优先级队列** @param str* @return*/private static String myPriorityQueue(String str) {//将输入解析为自定义对象DataString[] arrs = str.substring(1, str.length() - 1).split("\\),\\(");PriorityQueue<Data> queue = new PriorityQueue<>();for (int i = 0; i < arrs.length; i++) {String[] cur = arrs[i].split(",");Data data = new Data(Integer.parseInt(cur[1]), Integer.parseInt(cur[0]),i);queue.add(data);}StringBuilder sb = new StringBuilder();Data lst = null;int size = queue.size();while (!queue.isEmpty()) {Data data = queue.poll();if (!data.equals(lst)) {lst = data;if (size != queue.size()+1) sb.append(",");sb.append(data.getVal());}}return sb.toString();}
}

自定义数据结构实现

package hwod;import java.util.*;
import java.util.stream.Collectors;public class MyPriorityQueue {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String inputs = sc.nextLine();System.out.println(myPriorityQueue(inputs));}/*** 用两个栈实现优先级对列** @param str* @return*/private static String myPriorityQueue2(String str) {//将输入解析为自定义对象DataString[] arrs = str.substring(1, str.length() - 1).split("\\),\\(");Myqueue queue = new Myqueue();for (int i = 0; i < arrs.length; i++) {String[] cur = arrs[i].split(",");Data data = new Data(Integer.parseInt(cur[1]), Integer.parseInt(cur[0]));queue.add(data);}StringBuilder sb = new StringBuilder();int size = queue.getSize();while (!queue.isEmpty()) {if (queue.getSize() != size) sb.append(",");sb.append(queue.remove().getVal());}return sb.toString();}
}
class Myqueue {private LinkedList<Data> stackA = new LinkedList<>();//存小数,大堆顶private LinkedList<Data> stackB = new LinkedList<>(); //存大数,小堆顶public void add(Data data) {if (stackB.isEmpty() || data.getPriority() <= stackB.peekLast().getPriority()) {//比stackB栈顶元素还小,说明是一个较低优先级,应该存在stackA中//和stackB栈顶元素相等,说明有两个优先级相等的data,比如(30,1),(10,1),题目要求按照输入顺序输出,那么可以等价于后出现的优先级相对更低// 即此处的优先级等于和小于等价while (!stackA.isEmpty() && data.getPriority() <= stackA.peekLast().getPriority()) {stackB.addLast(stackA.removeLast());}//优先级相等时,始终会把之前的数据放入stackB中去if (!stackB.isEmpty() && stackB.peekLast().equals(data)) return;stackA.addLast(data);} else {while (!stackB.isEmpty() && data.getPriority() > stackB.peekLast().getPriority()) {stackA.addLast(stackB.removeLast());}if (!stackB.isEmpty() && stackB.peekLast().equals(data)) return;stackB.addLast(data);}}public Data remove() {while (!stackB.isEmpty()) {stackA.addLast(stackB.removeLast());}return stackA.removeLast();}public int getSize() {return stackA.size() + stackB.size();}public boolean isEmpty() {return getSize() == 0;}
}

推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/174591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣6:N字形变化

代码&#xff1a; class Solution { public:string convert(string s, int numRows){int lens.size();if(numRows1){return s;}int d2*numRows-2;int count0;string ret;//第一行&#xff01;for(int i0;i<len;id){rets[i];}//第k行&#xff01;for(int i1;i<numRows-1;…

【云备份】配置加载文件模块

文章目录 配置信息设计配置文件加载cloud.conf配置文件单例模式的使用ReadConfigFile —— 读取配置文件GetInstance —— 创建对象其他函数的实现 具体实现cloud.confconfig.hpp 配置信息设计 使用文件配置加载一些程序运行的关键信息 可以让程序的运行更加灵活 配置信息&am…

爬取极简壁纸

js反编译的代码需要解密之类的&#xff0c;直接给我干蒙圈了&#xff0c;借助selenium可以直接获取到调式工具中的源码&#xff0c;可以获取渲染后的链接&#xff0c;然后将链接交给下载函数&#xff08;使用异步提高效率&#xff09;即可。 后续学习完js反编译的话&#xff0…

羊大师:不同时段喝羊奶,效果会有何不同?

羊大师&#xff1a;不同时段喝羊奶&#xff0c;效果会有何不同&#xff1f; 羊奶是一种营养丰富、口感香浓的健康饮品&#xff0c;被广大消费者所喜爱。然而&#xff0c;你是否知道&#xff0c;不同的喝奶时间对身体的影响也是不同的呢&#xff1f;在不同时段喝羊奶&#xff0…

【无头双向链表和链表练习题2】

文章目录 以给定值x为基准将链表分割成两部分&#xff0c;所有小于x的结点排在大于或等于x的结点之前输入两个链表&#xff0c;找出它们的第一个公共结点。给定一个链表&#xff0c;判断链表中是否有环无头双向链表的模拟实现ArrayList&#xff08;顺序表&#xff09;和LinkedL…

矢量图片转换软件Vector Magic mac中文版功能特色

Vector Magic mac是一款图片转换矢量图&#xff0c;该软件使用世界上最好的全彩色自动描摹器&#xff0c;快速准备好您的作品进行打印、绣花、剪裁等操作。 Vector Magic mac功能特色 只需上传即可在线自动将 JPG、PNG、BMP 和 GIF 位图图像转换为真正的 SVG、Eps 和 PDF 矢量…

避免手机无节制使用

手机使用情况分析 使用时间 我挑选了11月份某一周的统计数据&#xff0c;可以看到&#xff0c;我的日均手机手机时间达到了惊人的8个小时&#xff0c;每周总共余约57小时。 按照使用软件的类型来分类&#xff0c;其中约%50用于娱乐&#xff0c;主要使用软件为&#xff1a;哔哩…

Django总结

文章目录 一、Web应用Web应用程序的优点Web应用程序的缺点应用程序有两种模式C/S、B/S C/S 客户端/服务端局域网连接其他电脑的MySQL数据库1.先用其他电脑再cmd命令行ping本机ip2.开放MySQL的访问 B/S 浏览器/服务端基于socket编写一个Web应用 二、Http协议1.http协议是什么2.h…

【上海大学数字逻辑实验报告】一、基本门电路

一、 实验目的 熟悉TTL中、小规模集成电路的外形、管脚和使用方法&#xff1b;了解和掌握基本逻辑门电路的输入与输出之间的逻辑关系及使用规则。 二、 实验原理 实现基本逻辑运算和常用逻辑运算的单元电路称为逻辑门电路。门电路通常用高电平VH表示逻辑值“1”&#xff0c;…

为啥网络安全那么缺人,但很多人却找不到工作?

文章目录 一、学校的偏向于学术二、学的东西太基础三、不上班行不行 为什么网络安全的人才缺口那么大&#xff0c;但是大学毕业能找到网安工作的人却很少&#xff0c;就连招聘都没有其他岗位多&#xff1f; 明明央视都说了网络安全的人才缺口还有300多万&#xff0c;现在找不到…

Java远程连接本地开源分布式搜索引擎ElasticSearch

文章目录 前言1. Windows 安装 Cpolar2. 创建Elasticsearch公网连接地址3. 远程连接Elasticsearch4. 设置固定二级子域名 前言 简单几步,结合Cpolar内网穿透工具实现Java远程连接操作本地Elasticsearch。 什么是elasticsearch&#xff1f;一个开源的分布式搜索引擎&#xff0…

Redux在React中的使用

Redux在React中的使用 1.构建方式 采用reduxjs/toolkitreact-redux的方式 安装方式 npm install reduxjs/toolkit react-redux2.使用 ①创建目录 创建store文件夹&#xff0c;然后创建index和对应的模块&#xff0c;如上图所示 ②编写counterStore.js 文章以counterStore…

JavaScript解构对象

之前介绍了数组解构&#xff0c;本文来介绍一下对象如何解构&#xff1b; 前言 现在我们有这样的一个数组&#xff1a; const restaurant {name: Classico Italiano,location: Via Angelo Tavanti 23, Firenze, Italy,categories: [Italian, Pizzeria, Vegetarian, Organic…

safari浏览器,直接安装ipa文件

蒲公英二维码方法 个人开发者账号发布证书AD-hoc 描述文件蒲公英上传链接通过苹果safari 浏览器下载IPA包 浏览器下载方法 前置条件 1.下载 ipa 包的设备的 uuid 已加入 苹果测试设备列表如何添加到测试列表 2.web 服务, 文件服务. 3.需要AD-hoc 描述文件 添加链接描述 1.创…

【shell】正则表达式和文本三剑客之grep和awk

目录 一、正则表达式 1.1用法 1.2表示字符匹配 1.3表示次数 1.4表示位置锚定 1.5表示分组或其他 1.6扩展正则表达式 二、grep命令 三、awk命令 3.1awk与vim的区别 3.2awk的语法 3.3基础用法 test1.提取磁盘的分区利用率 test2.提取用户名和uid号 test3.提取ip地址…

探究Kafka原理-5.Kafka设计原理和生产者原理解析

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

Linux基础项目开发1:量产工具——程序框架(一)

前言&#xff1a; 前面已经将Linux应用开发基础知识学习完了&#xff0c;现在让我们来做个小项目练练手&#xff0c;对之前的一些知识点进行一个更加具体详细的认识与了解&#xff0c;我们要进行的项目名称为&#xff1a;电子产品量产测试与烧写工具&#xff0c;这是一套软件&a…

YOLOv8改进 | SAConv可切换空洞卷积(附修改后的C2f+Bottleneck)

论文地址&#xff1a;官方论文地址 代码地址&#xff1a;官方代码地址 一、本文介绍 本文给大家带来的改进机制是可切换的空洞卷积&#xff08;Switchable Atrous Convolution, SAC&#xff09;是一种创新的卷积网络机制&#xff0c;专为增强物体检测和分割任务中的特征提取而…

五子棋游戏

import pygame #导入pygame模块 pygame.init()#初始化 screen pygame.display.set_mode((750,750))#设置游戏屏幕大小 running True#建立一个事件 while running:#事件运行for event in pygame.event.get():if event.type pygame.QUIT:#当点击事件后退出running False #事…

李峋同款爱心代码

李峋爱心代码 背景代码运行pycharm打包成exe程序 背景 最近大火的电视剧《点燃我温暖你》出现&#xff0c;令我的家庭地位进一步下降&#xff0c;因为男主“李峋”已经变成了她的大老公&#xff0c;而我就被打入冷宫. 为了满足她的“攀比心”&#xff0c;我连夜给她实现了粉红色…