java算法day10

java算法day10

  • 239滑动窗口最大值
  • 347前k个高频元素

239滑动窗口最大值

看灵神的题解学会的
在这里插入图片描述
精髓就在这张图
这个题用到了单调队列。首先知道为什么要使用单调队列,从这个问题来知道单调队列的好处。
首先就是我们模拟的窗口。滑动的这个过程显然就是一个队列元素出队进队的过程。但是现在我们需要一个附加条件,就是需要在每次移动之后,队列告诉我们里面的最大值是什么。
所以这就是单调队列的用武之地,单调队列的队顶到队尾是递减关系。

这个解法就是用双端队列ArrayDeque来模拟单调队列。用ArrayDeque来模拟就是因为他有方法可以直接获取队列中的最大元素,因为最大元素就在某一侧,可以用poll方法来进行获取。

注意:
1.既然是单调队列,那么队列中就要一直保持单调递减。
2.队列里存的并不是元素本身,而是元素的索引。存索引也是为了方便队头元素的弹出。

模拟思路:

class Solution {public int[] maxSlidingWindow(int[] nums, int k) {int n = nums.length;//结果集就是数组总长减去窗口长度+1,+1是因为窗口刚好覆盖的地方也是结果。int[] ans = new int[n-k+1];Deque<Integer> q = new ArrayDeque<>();for(int i = 0;i<n;i++){//入,入的时候要比较队尾,因为要保持单调队列的特征,一旦队尾元素比即将入队的元素小,那就直接弹出,弹出的原因就是,有这个即将入队的元素在,比该元素小的元素就没有成为最大值的可能。这也与单调队列的理念不谋而合。一旦队列空了,那也没必要比了,就直接入。
while(!q.isEmpty()&&nums[q.peekLast()]<=nums[i]){q.pollLast();}q.offerLast(i);//出。出只发生在队头,一旦当前索引-队头索引=k,注意一定要等,自己模拟一下,试想窗口为3,3-0的情况。队头直接弹出。if(i-q.peekFirst()>=k){q.pollFirst();}//记录答案//因为是从数组的一开始才进行进队操作,所以在i>=k-1,即窗口还没覆盖数组之前是没必要记录答案的,覆盖之后才用记录答案。所以这个放在这里也是因为,前面已经完成了入队和出队操作,i>=k-1就是窗口刚好覆盖数组的时候,所以取队顶(最大值)加入结果集。if(i>=k-1){ans[i-k+1] = nums[q.peekFirst()];}}return ans;}
}

347前k个高频元素

这题学了优先队列。
首先java中已经实现了优先队列。PriorityQueue,在了解了之后,发现,这东西本质其实就是个堆。

优先队列补充

PriorityQueue 在 Java 中的实现和使用:

内部实现:
PriorityQueue 是 Java 标准库中已经实现好的数据结构。
默认使用最小堆(小根堆)实现。

定义比较器:
您可以通过提供一个自定义的 Comparator 来改变 PriorityQueue 的行为。
这个 Comparator 定义了元素之间的优先级关系。

大根堆 vs 小根堆:
默认(不提供 Comparator):小根堆
提供自定义 Comparator:可以实现大根堆或其他自定义优先级
使用示例:

// 默认小根堆
PriorityQueue minHeap = new PriorityQueue<>();

// 大根堆
PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> b - a);

// 自定义对象的优先队列
PriorityQueue pq = new PriorityQueue<>((p1, p2) -> p1.getAge() - p2.getAge());

关键点:
您不需要自己实现堆的底层逻辑(如上浮、下沉等操作)。
您只需要定义元素之间的优先级关系。
PriorityQueue 会根据您提供的比较逻辑自动维护堆的性质。

常用方法:
offer(E e): 添加元素
poll(): 移除并返回队首元素(最高优先级)
peek(): 返回队首元素但不移除
size(): 返回队列中的元素个数

性能:
插入和删除操作的时间复杂度为 O(log n)
因为有调整操作,才导致了他O(logn)。
访问队首元素的时间复杂度为 O(1)

总结:PriorityQueue 确实是 Java 已经实现好的,您只需要根据需要定义比较器来决定优先级的顺序(是大根堆还是小根堆,或其他自定义优先级)。这大大简化了在需要优先队列的场景中的编程工作。

比较器补充

关于比较器,我的建议是里面的compare规则记下来就好。不用去深究。
1.比较器的用处:
就是用来维护堆的性质的,因为比较器,才定义了是大顶堆还是小顶堆。每次插入或删除操作之后,它都会确保堆顶元素是当前堆中最小的元素。
2.如何定义:
直接记下来

基本规则:
o1 - o2 > 0:o1 排在 o2 后面
o1 - o2 < 0:o1 排在 o2 前面
o1 - o2 = 0:o1 和 o2 相等,顺序无关紧要
升序排序: 直接使用 o1 - o2 的逻辑

降序排序: 反转比较逻辑,使用 o2 - o1

实际应用

// 升序
(o1, o2) -> o1.getSomeValue() - o2.getSomeValue()

// 降序
(o1, o2) -> o2.getSomeValue() - o1.getSomeValue()

注意事项
对于整数比较,直接相减可能导致溢出,可以使用 Integer.compare()
对于浮点数,使用 Double.compare() 或 Float.compare()
对于字符串,可以直接使用 String.compareTo()
复杂比较: 对于多字段比较,可以组合多个比较结果

我下面定义小顶堆的完整写法

PriorityQueue<Map.Entry<Integer,Integer>> queue = new PriorityQueue<>(new Comparator<Map.Entry<Integer,Integer>>() {@Overridepublic int compare(Map.Entry<Integer,Integer> o1, Map.Entry<Integer,Integer> o2) {return o1.getValue() - o2.getValue();}}
);

怎么看出他是定义小顶堆,直接从比较器看,大于0表示o1排o2后面,所以排前面的就是小的。所以从维护的这个堆来看,小的排前面,那就是堆顶排最前面所以是小顶堆。


解题思路:
创建一个大小为k的小顶堆,然后将map里的元素加入小顶堆当中,在遍历map的过程中,频次小的就会弹出,最终频次大的会留在堆中。然后把堆里面的元素弹出,收集结果就行了。

class Solution {public int[] topKFrequent(int[] nums, int k) {//结果集int[] result = new int[k];//弄一个map用于统计频次HashMap<Integer,Integer> map = new HashMap<>();//遍历统计频次for(int num : nums){map.put(num,map.getOrDefault(num,0)+1);}//遍历map。Set<Map.Entry<Integer,Integer>> entries = map.entrySet();//搞一个小顶堆,必须是小顶堆。PriorityQueue<Map.Entry<Integer,Integer>> queue = new PriorityQueue<>((o1,o2)-> o1.getValue()-o2.getValue());for(Map.Entry<Integer,Integer> entry : entries){//每次都要入队。queue.offer(entry);//入完队,要检查队列是不是超k个了,因为要始终维护一个长度为k的优先队列。//超了就弹出if(queue.size()>k){queue.poll();}}//一边弹出,一边收集结果。for(int i = k-1;i>=0;i--){result[i] = queue.poll().getKey();}return result;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

《梦醒蝶飞:释放Excel函数与公式的力量》10.3 IMABS函数

第一节 10.3 IMABS函数 10.3.1 函数简介 IMABS函数是Excel中的一个工程函数&#xff0c;用于计算复数的绝对值&#xff08;模&#xff09;。在工程和科学计算中&#xff0c;复数的模是一个重要的概念&#xff0c;表示复数在复平面上到原点的距离。 10.3.2 语法&#xff1a; …

MT5016A-ASEMI逆变焊机专用MT5016A

编辑&#xff1a;ll MT5016A-ASEMI逆变焊机专用MT5016A 型号&#xff1a;MT5016A 品牌&#xff1a;ASEMI 封装&#xff1a;KBPC-4 批号&#xff1a;2024 现货&#xff1a;50000 正向电流&#xff08;Id&#xff09;&#xff1a;50A 反向耐压&#xff08;VRRM&#xff0…

内存迎来革命性升级,只装一条就能组成双通道

相信用过台式机的同学或多或少都遇到过一个情况&#xff0c;那就是按下开机键后&#xff0c;除了显示器不亮&#xff0c;哪儿都亮。 拿着自己的故障满世界发帖求助&#xff0c;得到最多的回答就是&#xff0c;断电拔下内存用橡皮擦擦擦金手指再装回。而这样的操作确实能解决大部…

Java中的集合类有哪些?如何分类的?

一、典型回答 Java的整个集合框架中&#xff0c;主要分为List、Set、Queue、Stack、Map等五种数据结构。其中&#xff0c;前四种数据结构都是单一元素的集合&#xff0c;而最后的Map则是以KV&#xff08;键值&#xff09;对的形式使用。 从继承关系上讲&#xff0c;List、Set、…

odoo模型继承

odoo模型继承 模块化是Odoo一个非常重要的功能。一个模块通常定义一块业务内容&#xff0c;模块之间是可以交互的。所以从已有模块中去继承修改原有模块功能就很有必要。 Odoo中&#xff0c;模型之间也定义了一套继承的逻辑&#xff0c;目前有三种继承方 式&#xff1a; 1、…

[图解]SysML和EA建模住宅安全系统-14-黑盒系统规约

1 00:00:02,320 --> 00:00:07,610 接下来&#xff0c;我们看下一步指定黑盒系统需求 2 00:00:08,790 --> 00:00:10,490 就是说&#xff0c;把这个系统 3 00:00:11,880 --> 00:00:15,810 我们的目标系统&#xff0c;ESS&#xff0c;看成黑盒 4 00:00:18,030 --> …

萌啦数据多少钱一个月,萌啦数据价格是多少

在跨境电商的浩瀚星海中&#xff0c;Ozon作为俄罗斯及独联体地区领先的电商平台&#xff0c;正吸引着越来越多的商家和创业者的目光。而“萌啦ozon数据”作为专注于Ozon平台数据分析与洞察的服务提供商&#xff0c;更是成为了众多商家在数据驱动决策道路上的得力助手。然而&…

怎么选择渲染农场?渲染100邀请码1a12

市面上的渲染农场那么多&#xff0c;到底选择哪一个呢&#xff1f;这次我给大家提供几个指标&#xff0c;以供参考。 1、机器性能&#xff1a;农场的机器性能会直接影响到渲染速度&#xff0c;速度越快项目就能越早完成&#xff0c;所以机器性能是重要的衡量指标。2、渲染价格…

YOLOv5改进 | 注意力机制| 对密集和小目标友好的EVAblock【完整代码 + 小白轻松上手】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 改…

七人共赢拼团模式的深度剖析与互助精神重塑

在当今电商的浩瀚星海中&#xff0c;七人共赢拼团模式以其创新的合作框架与激励体系&#xff0c;正引领着消费与商业的新潮流。这一模式不仅优化了购物体验&#xff0c;更深刻诠释了互助共赢的核心理念。以下&#xff0c;我们将从直推奖励、自动补齐机制及团队荣耀奖三个方面&a…

井字游戏00

题目链接 井字游戏 题目描述 注意点 1 < board.length board[i].length < 100输入一定遵循井字棋规则 解答思路 如果某一方想要获胜&#xff0c;则其需要占满某一行或某一列或对角线&#xff0c;所以只需要根据第一行和第一列判断是否填充完某一行或某一列或对角线…

「解析」Cosine-Warmup 学习率策略

参考论文&#xff1a;SGDR: Stochastic Gradient Descent with Warm Restarts Bag of Tricks for Image Classification with Convolutional Neural Networks 梯度下降算法需要我们设置一个值&#xff0c;用来控制权重更新幅度&#xff0c;我们将其称之为学习率。它是控制模型学…

Python虚拟环境:Virtualenv和Pipenv的安装理解与使用

Python虚拟环境&#xff1a;Virtualenv和Pipenv的安装理解与使用 引言 在Python开发中&#xff0c;一个常见的问题是不同项目依赖不同版本的库&#xff0c;这可能导致版本冲突。为解决这个问题&#xff0c;Python社区创造了虚拟环境工具&#xff0c;如Virtualenv和Pipenv。本…

使用Go编写的持续下行测速脚本,快速消耗流量且不伤硬盘

介绍 使用go语言编写的持续下行测速脚本,可用于任意平台使用,通过指定URL清单文本文件自动遍历测速,支持多线程,支持多平台 特性 轻量级,无依赖采用内存进行缓存数据,不占用磁盘(如果内存较小请使用gcd项目)&#xff0c;最大程度减少磁盘IO,保护硬盘寿命可自定义最大下载文件…

队列+二叉树广度优先

题目出自力扣-n叉树的层序遍历 我是原始人&#xff0c;递归写出一道题就只有递归思路&#xff0c;开始的想法是写深搜函数&#xff0c;传一个随着层数递增的int参数q&#xff0c;节点空就return&#xff0c;否则遍历所有节点&#xff0c;每个子节点又以q1为层数递归&#xff…

项目实战--本地缓存方案选型及使用缓存的坑

一、摘要 在互联网公司面试时&#xff0c;说到缓存&#xff0c;面试官基本上会绕不开的几个话题&#xff1a;项目中哪些地方用到了缓存&#xff1f;为什么要使用缓存&#xff1f;怎么使用它的&#xff1f;引入缓存后会带来哪些问题&#xff1f; 引入缓存&#xff0c;其实主要…

lvs集群、NAT模式和DR模式

lvs集群概念 全称是linux virtual server&#xff0c;是在Linux的内核层面实现负载均衡的软件。 主要作用&#xff1a;将多个后端服务器组成一个高可用高性能的服务器集群&#xff0c;通过负载均衡的算法将客户端的请求分发到后端的服务器上&#xff0c;来实现高可用和负载均…

百元挂耳式耳机哪个品牌音质好、五大优质臻品错过可惜!

开放式耳机这么火&#xff0c;相信大家也都知道了吧&#xff0c;它避免了入耳式耳机对耳道的直接压迫&#xff0c;为用户提供了更加自然、舒适的佩戴体验。长时间使用不再感觉耳朵被束缚。但是面对市面上众多的开放式耳机品牌和产品&#xff0c;百元挂耳式耳机哪个品牌音质好&a…

米家立式学习灯怎么样?书客、米家、孩视宝三款护眼大路灯巅峰PK!

米家立式学习灯怎么样?不知从什么时候开始&#xff0c;青少年成为了近视重灾区&#xff0c;主要促成近视的原因有长时间接触电子产品、学习时的不正确姿势、不良的灯光环境等&#xff0c;除了减少电子产品的使用以及多室外活动之外&#xff0c;剩下的就是室内孩子经常学习的光…

软件渗透测试有哪些测试流程?专业CMA、CNAS软件测评机构推荐

最近几年&#xff0c;随着互联网的迅猛发展和各种网络安全事件的频发&#xff0c;软件渗透测试逐渐成为了软件开发过程中不可或缺的一环。那么&#xff0c;什么是软件渗透测试呢?软件渗透测试&#xff0c;顾名思义就是对软件系统中的安全漏洞进行评估和检测的过程&#xff0c;…