Hot100之堆

我们的PriorityQueue默认为最小堆,堆顶总是为最小 

215数组中的第K个最大元素

题目

思路解析

暴力解法(不符合时间复杂度)

题目要求我们找到「数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素」。「数组排序后的第 k 个最大的元素」换句话说:从右边往左边数第 k 个元素(从 1 开始),那么从左向右数是第几个呢,我们列出几个找找规律就好了。

一共 6 个元素,找第 2 大,下标是 4;

一共 6 个元素,找第 4 大,下标是 2。

因此升序排序以后,目标元素的下标是 N−k,这里 N 是输入数组的长度

Arrays.sort(nums);
return nums[nums.length - k];

优先队列解法(堆)

我们维护一个数量为K的优先队列

我们的PriorityQueue默认为最小堆,堆顶总是为最小

所以我们一次遍历,每次数量大于K的时候踢出最小的

这样子我们遍历完后,我们就留下来了k个最大的值,第一个堆顶元素就是第K个最大的元素


最小堆的进一步优化

当我们的堆里元素为K个时,此时我们的要添加的num小于堆里面的最小值

我们可以不添加直接continue跳过

为什么一定要堆里面元素个数到k个的时候呢?

因为要是我们的数组元素总个数==K的时候

我们按那个跳过逻辑来弄,我们示例【2,1】,k=2

我们for循环会导致我们的元素【2】进去了堆,但是我们的元素【1】没进去堆,导致漏添加了元素


代码

暴力解法(不符合时间复杂度)
class Solution {public int findKthLargest(int[] nums, int k) {Arrays.sort(nums);return nums[nums.length - k];}}

优先队列解法(堆)
class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> heap=new PriorityQueue<>();for(int num:nums){heap.add(num);if(heap.size()>k){heap.poll();}   }return heap.peek();}}

最小堆的进一步优化
class Solution {public int findKthLargest(int[] nums, int k) {PriorityQueue<Integer> heap=new PriorityQueue<>();for(int num:nums){if(heap.size()==k&&num<heap.peek())continue;heap.add(num);if(heap.size()>k){heap.poll();}   }return heap.peek();}}

347前K个高频元素

题目

思路解析

首先我们把所有的值到放到Map结构里面

然后我们把这个Map结构map.entrySet()弄到Map结构里面

弄一个小顶堆,我们根据value来进行排序,正序,从小到大

Set<Map.Entry<Integer, Integer>> entries = map.entrySet();// 根据map的value值正序排,相当于一个小顶堆
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) 
-> o1.getValue() - o2.getValue());

我们把EntrySet结构加入到优先队列,他会按照value大小,正序,从小到大排序

for (Map.Entry<Integer, Integer> entry : entries) {queue.offer(entry);if (queue.size() > k) {queue.poll();}}

遍历顺序

我们因为是小顶堆,但是我们最前面的一个是我们的频率最大的值

所以我们result【】数组要倒序加入我们的值

for (int i = k - 1; i >= 0; i--) {result[i] = queue.poll().getKey();}

代码

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);}Set<Map.Entry<Integer, Integer>> entries = map.entrySet();// 根据map的value值正序排,相当于一个小顶堆PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue());for (Map.Entry<Integer, Integer> entry : entries) {queue.offer(entry);if (queue.size() > k) {queue.poll();}}for (int i = k - 1; i >= 0; i--) {result[i] = queue.poll().getKey();}return result;}
}

295数据流的中位数 

题目

思路解析

left最大堆和right最小堆的意义

中位数把这 6 个数均分成了左右两部分,一边是 left=[1,2,3],另一边是 right=[4,5,6]。

我们要计算的中位数,就来自 left 中的最大值,以及 right 中的最小值

随着 addNum 不断地添加数字,我们需要:

1.保证 left 的大小和 right 的大小尽量相等。规定:在有奇数个数时,left 比 right 多 1 个数。

2.保证 left 的所有元素都小于等于 right 的所有元素。

只要时时刻刻满足以上两个要求(满足中位数的定义),我们就可以用 left 中的最大值以及 right 中的最小值计算中位数

分类讨论
如果当前 left 的大小和 right 的大小相等(并下一步往right添加元素)

如果添加的数字 num 比较大,比如添加 7,那么把 7 加到 right 中

现在 left 比 right 少 1 个数,不符合前文的规定,所以必须把 right 的最小值从 right 中去掉,添加到 left 中。如此操作后,可以保证 left 的所有元素都小于等于 right 的所有元素。

如果添加的数字 num 比较小,比如添加 0,那么把 0 加到 left 中。

这两种情况可以合并:无论 num 是大是小,都可以先把 num 加到 right 中,然后把 right 的最小值从 right 中去掉,并添加到 left 中

如果当前 left 比 right 多 1 个数(并下一步往left添加元素)

如果添加的数字 num 比较大,比如添加 7,那么把 7 加到 right 中。

如果添加的数字 num 比较小,比如添加 0,那么把 0 加到 left 中。现在 left 比 right 多 2 个数,不符合前文的规定,所以必须把 left 的最大值从 left 中去掉,添加到 right 中。如此操作后,可以保证 left 的所有元素都小于等于 right 的所有元素。

这两种情况可以合并:无论 num 是大是小,都可以先把 num 加到 left 中,然后把 left 的最大值从 left 中去掉,并添加到 right 中

总结

我们left是最大堆

我们right是最小堆

left.size()==right.size()的情况

然后我们往right添加元素,然后right是最小堆,我们让right中元素的最小值移动到left,变成left.size()>right.size()的情况

此时就是left.size()>right.size()的情况

我们往left添加元素,然后left是最大堆,我们让left中元素的最大值移动到right,这样子又变成了元素个数相等的情况

如果我们的left.size()>right.size(),因为我们的逻辑让left中的元素只能比right中最多多一个

所以此时left的最大值就是中位数

如果我们的left.size()==right.size(),我们的中位数是【(left的最大值)+(right的最小值)】/2.0

代码

class MedianFinder {//最大堆private final PriorityQueue<Integer> left=new PriorityQueue<>((a,b)->b-a);//最小堆private final PriorityQueue<Integer> right=new PriorityQueue<>();public MedianFinder() {}public void addNum(int num) {if(left.size()==right.size()){//两个堆内元素个数相等的情况,我们往right添加元素//然后弹出right的最小值加入到left里面right.offer(num);left.offer(right.poll());}else{//当left的元素>right的元素,我们往left添加元素//然后弹出left的最大值加入到right里面left.offer(num);right.offer(left.poll());}        }public double findMedian() {if(left.size()>right.size()){return left.peek();}return(left.peek()+right.peek())/2.0;}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/

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

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

相关文章

FinRobot:一个使用大型语言模型的金融应用开源AI代理平台

“FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models” 论文地址&#xff1a;https://arxiv.org/pdf/2405.14767 Github地址&#xff1a;https://github.com/AI4Finance-Foundation/FinRobot 摘要 在金融领域与AI社区间&a…

算法题(57):找出字符串中第一个匹配项的下标

审题: 需要我们根据原串与模式串相比较并找到完全匹配时子串的第一个元素索引&#xff0c;若没有则返回-1 思路&#xff1a; 方法一&#xff1a;BF暴力算法 思路很简单&#xff0c;我们用p1表示原串的索引&#xff0c;p2表示模式串索引。遍历原串&#xff0c;每次遍历都匹配一次…

「全网最细 + 实战源码案例」设计模式——策略模式

核心思想 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一系列算法或策略&#xff0c;将它们封装成独立的类&#xff0c;并使它们可以相互替换&#xff0c;而不影响客户端的代码&#xff0c;提高代码的可维护性和扩展性。 结构 …

linux 进程补充

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪 里&#xff0c;但是照样可以链接成功&#…

排序算法--选择排序

选择排序虽然简单&#xff0c;但时间复杂度较高&#xff0c;适合小规模数据或教学演示。 // 选择排序函数 void selectionSort(int arr[], int n) {for (int i 0; i < n - 1; i) { // 外层循环控制当前最小值的存放位置int minIndex i; // 假设当前位置是最小值的索引// 内…

java求职学习day27

数据库连接池 &DBUtils 1.数据库连接池 1.1 连接池介绍 1) 什么是连接池 实际开发中 “ 获得连接 ” 或 “ 释放资源 ” 是非常消耗系统资源的两个过程&#xff0c;为了解决此类性能问题&#xff0c;通常情况我们 采用连接池技术&#xff0c;来共享连接 Connection 。…

接入DeepSeek大模型

接入DeepSeek 下载并安装Ollamachatbox 软件配置大模型 下载并安装Ollama 下载并安装Ollama&#xff0c; 使用参数ollama -v查看是否安装成功。 输入命令ollama list&#xff0c; 可以看到已经存在4个目录了。 输入命令ollama pull deepseek-r1:1.5b&#xff0c; 下载deepse…

AI大模型(二)基于Deepseek搭建本地可视化交互UI

AI大模型&#xff08;二&#xff09;基于Deepseek搭建本地可视化交互UI DeepSeek开源大模型在榜单上以黑马之姿横扫多项评测&#xff0c;其社区热度指数暴涨、一跃成为近期内影响力最高的话题&#xff0c;这个来自中国团队的模型向世界证明&#xff1a;让每个普通人都能拥有媲…

防火墙安全策略实验

一、实验拓扑图及实验要求 实验要求&#xff1a; 1、VLAN2属于办公区&#xff1b;VLAN 3属于生产区。 2、办公区PC在工作日时间&#xff08;周一至周五&#xff0c;早8到晚6)可以正常访问0A Server&#xff0c;其他时间不允许。 3、办公区可以在任意时刻访问web Server 4、生产…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】3.1 NumPy图像大小调整实战

3.1 NumPy图像大小调整实战 目录 #mermaid-svg-uDg4hyooC74c0r2r {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uDg4hyooC74c0r2r .error-icon{fill:#552222;}#mermaid-svg-uDg4hyooC74c0r2r .error-text{fill:#5…

AI 编程工具—Cursor进阶使用 Agent模式

AI 编程工具—Cursor进阶使用 Agent模式 我们在使用Cursor 的是有,在Composer 模式下,提交的是有两种模式 Normal 模式,也就是默认的模式Agent 模式Agent 模式可以帮我们生成代码文件,执行程序,安装依赖,并且完成一些列的工作 这里有个点很重要就是在Agent 模式下,Cur…

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步&#xff1a;创建模块counterStore 第二步&#xff1a;在store的入口文件进行子模块的导入组合 第三步&#xff1a;在index.js中进行store的全局注入 第四步&#xff1a;在组件中进行使用 第五步&#xff1a;在组件中…

Leetcode - 周赛434

目录 一、3432. 统计元素和差值为偶数的分区方案二、3433. 统计用户被提及情况三、3434. 子数组操作后的最大频率四、3435. 最短公共超序列的字母出现频率 一、3432. 统计元素和差值为偶数的分区方案 题目链接 本题可以直接模拟&#xff0c;这里再介绍一个数学做法&#xff0…

Linux: 网络基础

1.协议 为什么要有协议&#xff1a;减少通信成本。所有的网络问题&#xff0c;本质是传输距离变长了。 什么是协议&#xff1a;用计算机语言表达的约定。 2.分层 软件设计方面的优势—低耦合。 一般我们的分层依据&#xff1a;功能比较集中&#xff0c;耦合度比较高的模块层…

Spring Boot常用注解深度解析:从入门到精通

今天&#xff0c;这篇文章带你将深入理解Spring Boot中30常用注解&#xff0c;通过代码示例和关系图&#xff0c;帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解&#xff1a; SpringBootApplication Confi…

【大模型理论篇】DeepSeek-R1:引入冷启动的强化学习

1. 背景 首先给出DeepSeek-V3、DeepSeek-R1-Zero、DeepSeek-R1的关系图【1】。 虽然DeepSeek-R1-Zero推理能力很强&#xff0c;但它也面临一些问题。例如&#xff0c;DeepSeek-R1-Zero存在可读性差和语言混杂等问题。为了使推理过程更具可读性&#xff0c;进而推出了DeepSee…

【BUUCTF杂项题】荷兰宽带数据泄露、九连环

一.荷兰宽带数据泄露 打开发现是一个.bin为后缀的二进制文件&#xff0c;因为提示宽带数据泄露&#xff0c;考虑是宽带路由器方向的隐写 补充&#xff1a;大多数现代路由器都可以让您备份一个文件路由器的配置文件&#xff0c;软件RouterPassView可以读取这个路由配置文件。 用…

院校联合以项目驱动联合培养医工计算机AI人才路径探析

一、引言 1.1 研究背景与意义 在科技飞速发展的当下&#xff0c;医疗人工智能作为一个极具潜力的新兴领域&#xff0c;正深刻地改变着传统医疗模式。从疾病的早期诊断、个性化治疗方案的制定&#xff0c;到药物研发的加速&#xff0c;人工智能技术的应用极大地提升了医疗服务…

解读“大语言模型(LLM)安全性测评基准”

1. 引入 OWASP&#xff0c;全称为Open Web Application Security Project&#xff0c;即开放式Web应用程序安全项目&#xff0c;是一个致力于提高软件安全性的非营利国际组织。 由于庞大的规模和复杂的结构&#xff0c;大语言模型也存在多种安全风险&#xff0c;如prompt误导…

【大数据技术】教程03:本机PyCharm远程连接虚拟机Python

本机PyCharm远程连接虚拟机Python 注意:本文需要使用PyCharm专业版。 pycharm-professional-2024.1.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本地PyCharm远程连接虚拟机,运行Python脚本,提高编程效率。 注意: …