面试经典150题 堆

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

建堆算法实现-CSDN博客

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

中等

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

输入: [3,2,1,5,6,4], k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

进行建堆操作,每次将堆中的第一个元素(最大元素)执行删除操作,删除K次后,最近一次删除掉的元素即为数组中的第K个最大元素 

class Solution {// 找到数组中第 k 大的元素public int findKthLargest(int[] nums, int k) {// 构建初始堆heapify(nums, nums.length);int size = nums.length;// 进行 k 次操作,每次将堆顶元素与末尾元素交换,并调整堆for (int i = 0; i < k; i++) {// 交换堆顶元素和当前末尾元素swap(nums, 0, size - 1);// 调整堆,排除已确定的末尾元素down(nums, 0, --size);}// 返回堆顶元素,即第 k 大的元素return nums[size];}// 构建初始堆的方法private static void heapify(int[] nums, int size) {// 从最后一个非叶子节点开始,逐步调整堆for (int i = size / 2 - 1; i >= 0; i--) {down(nums, i, size);}}// 堆的下潜操作private static void down(int[] array, int parent, int size) {while (true) {int max = parent;int left = parent * 2 + 1;int right = left + 1;// 如果左子节点存在且大于当前最大元素,更新最大元素索引if (left < size && array[left] > array[max]) {max = left;}// 如果右子节点存在且大于当前最大元素,更新最大元素索引if (right < size && array[right] > array[max]) {max = right;}// 如果最大元素就是当前父节点,说明堆调整完成,退出循环if (max == parent) {break;}// 交换最大元素和父节点swap(array, max, parent);// 更新父节点索引,继续调整parent = max;}}// 交换数组中两个元素的方法private static void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}

502.IPO

502. IPO

困难

假设 力扣(LeetCode)即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限,它只能在 IPO 之前完成最多 k 个不同的项目。帮助 力扣 设计完成最多 k 个不同项目后得到最大总资本的方式。

给你 n 个项目。对于每个项目 i ,它都有一个纯利润 profits[i] ,和启动该项目需要的最小资本 capital[i] 。

最初,你的资本为 w 。当你完成一个项目时,你将获得纯利润,且利润将被添加到你的总资本中。

总而言之,从给定项目中选择 最多 k 个不同项目的列表,以 最大化最终资本 ,并输出最终可获得的最多资本。

答案保证在 32 位有符号整数范围内。

示例 1:

输入:k = 2, w = 0, profits = [1,2,3], capital = [0,1,1]
输出:4
解释:
由于你的初始资本为 0,你仅可以从 0 号项目开始。
在完成后,你将获得 1 的利润,你的总资本将变为 1。
此时你可以选择开始 1 号或 2 号项目。
由于你最多可以选择两个项目,所以你需要完成 2 号项目以获得最大的资本。
因此,输出最后最大化的资本,为 0 + 1 + 3 = 4。

示例 2:

输入:k = 3, w = 0, profits = [1,2,3], capital = [0,1,2]
输出:6

提示:

  • 1 <= k <= 105
  • 0 <= w <= 109
  • n == profits.length
  • n == capital.length
  • 1 <= n <= 105
  • 0 <= profits[i] <= 104
  • 0 <= capital[i] <= 109

理解题意:我们有一个现有的资本,一个所需资本和利润对应的投资元素,我们要进行投资资本就必须大于所需资本,要求K次投资能获得的最大资本。

贪心思想:在所有能投资的项目中,我们投资利润最大的那个。

思路:将资本和利润一一对应后,按照所需资本进行排序。

逐个遍历,将所有能投资的项目放入大根堆中,通过大根堆的性质选出利润最大的那一个进行投资,赚取利润后,再将我们目前能新投资的项目(我们赚取了利润,资本变多了)放入大根堆中,重复这个过程,直到投资的k次机会用完或者没有能投资的项目 

class Solution {// 找到最大化资本的方法public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {// 创建一个二维数组,用于存储资本和利润信息int total[][] = new int[profits.length][2];for (int i = 0; i < profits.length; i++) {// 将资本存入二维数组的第一列total[i][0] = capital[i];// 将利润存入二维数组的第二列total[i][1] = profits[i];}// 按照资本从小到大对二维数组进行排序Arrays.sort(total, (a, b) -> a[0] - b[0]);// 创建一个大顶堆优先队列,用于存储可选择的最大利润项目PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);int cur = 0;for (int i = 0; i < k; i++) {// 当还有未处理的项目且当前项目的资本小于等于当前资本 w 时while (cur < profits.length && total[cur][0] <= w) {// 将当前项目的利润加入优先队列pq.add(total[cur][1]);cur++;}// 如果优先队列不为空if (!pq.isEmpty()) {// 取出最大利润项目并增加当前资本 ww += pq.poll();} else {// 如果优先队列为空,无法进行操作,退出循环break;}}// 返回最终的资本 wreturn w;}
}

373.查找和最小的K对数字 

373. 查找和最小的 K 对数字

中等

给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 

定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 

请找到和最小的 k 个数对 (u1,v1) (u2,v2)  ...  (uk,vk) 。

示例 1:

输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
输出: [1,2],[1,4],[1,6]
解释: 返回序列中的前 3 对数:[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

示例 2:

输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
输出: [1,1],[1,1]
解释: 返回序列中的前 2 对数:[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]

提示:

  • 1 <= nums1.length, nums2.length <= 105
  • -109 <= nums1[i], nums2[i] <= 109
  • nums1 和 nums2 均为 升序排列
  • 1 <= k <= 104
  • k <= nums1.length * nums2.length

首先我们明确,最小的数字对一定是nums1[0] + nums2[0],比他们稍大的可能是nums1[0 + 1] + nums2[0]或者nums1[0] + nums2[0 + 1],这种情况对每一个找到的数字对都适用。

我们优先将nums1[0] + nums2[0]加入小顶堆中,采取循环的方式,每次找到一个最小数字对,就加入所有可能的下一个最小数字对,注意当我们找到的不是第一个最小数字对时(nums1[0] + nums2[0]),堆中所有的元素和新加入的数字对都有可能是下一个最小数字对。

注意这里有一个特殊情况,看例子2,我们所找到的数字对,元素可能是相同的,但是索引不能是相同的,而我们在加入数字对的过程中,可能加入索引相同的数字对,造成重复的情况,所以我们要使用hash进行去重,如果找到的数字对的索引我们已经使用过了,我们就不能把他们对应的元素加入结果数组中,去重后k++,因为我们没有找到一个新的最小数字对。

class Solution {public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {// 创建一个优先队列,用于存储二元组,按照两数之和的大小进行排序PriorityQueue<int[]> pq = new PriorityQueue<>(k, (o1, o2) -> {return nums1[o1[0]] + nums2[o1[1]] - nums1[o2[0]] - nums2[o2[1]];});// 用于存储最终结果的列表List<List<Integer>> result = new ArrayList<>();int length1 = nums1.length;int length2 = nums2.length;// 如果任一数组为空,直接返回空结果列表if (length1 == 0 || length2 == 0) {return result;}// 将第一个二元组(0,0)加入优先队列pq.offer(new int[]{0, 0});// 创建一个哈希表,用于存储已经处理过的二元组列表HashMap<List<Integer>, Integer> map = new HashMap<>();// 循环直到 k 次或者优先队列为空while (k-- > 0 &&!pq.isEmpty()) {// 取出优先队列中的二元组int[] temp = pq.poll();// 创建一个临时列表,存储当前二元组的索引List<Integer> mapList = new ArrayList<>();mapList.add(temp[0]);mapList.add(temp[1]);// 如果该二元组已经处理过,增加 k 的值,继续下一次循环if (map.containsKey(mapList)) {k++;continue;}// 将当前二元组列表加入哈希表map.put(mapList, 0);// 创建一个列表,存储当前二元组对应的两个数List<Integer> list = new ArrayList<>();list.add(nums1[temp[0]]);list.add(nums2[temp[1]]);// 将当前二元组对应的两个数的列表加入结果列表result.add(list);// 如果第一个数组还有下一个元素,将下一个二元组加入优先队列if (temp[0] + 1 < length1) {pq.offer(new int[]{temp[0] + 1, temp[1]});}// 如果第二个数组还有下一个元素,将下一个二元组加入优先队列if (temp[1] + 1 < length2) {pq.offer(new int[]{temp[0], temp[1] + 1});}}// 返回最终结果列表return result;}
}

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

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

相关文章

Leetcode - 周赛416

目录 一&#xff0c;3295. 举报垃圾信息 二&#xff0c;3296. 移山所需的最少秒数 三&#xff0c;3297. 统计重新排列后包含另一个字符串的子字符串数目 I 四&#xff0c;3298. 统计重新排列后包含另一个字符串的子字符串数目 II 一&#xff0c;3295. 举报垃圾信息 本题就是…

Linux 安装nginx

下载安装 https://nginx.org/en/download.html 解压 tar -zxvf nginx-1.26.2.tar.gz -C /opt chmod 777 -R /opt/nginx-1.26.2/编译 && 安装 # 安装到同目录以免乱套&#xff0c;一定要先创建目录 mkdir /opt/nginx-1.26.2/nginx/# 编译 make # 安装&#xff0c;大…

将Mixamo的模型和动画导入UE5

首先进入Mixamo的官网 , 点击 Character 选择一个模型 (当然你也可以自己上传模型/绑定动画) 然后点击下载 , 这个作为带骨骼的模型 选择FBX格式 , T Pose 直接下载 点击 Animations 选择动画 , 搜索 idle 默认站立动画 点击下载 , 格式选择 FBX , 不带模型只要骨骼 , 帧数选6…

MySQL_表_进阶(2/2)

上一章我们谈了排序子句&#xff0c;使用ORDER BY 字段 DESC/ASC。以及左右连接的多关系查询。 今天&#xff0c;没错&#xff0c;四张表最后两个需求 ✨涉及聚合函数查询与指定别名 四张表&#xff1a; 学院表&#xff1a;(testdb.dept) 课程表&#xff1a;(testdb.course) 选…

Rust编程的if选择语句

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 Rust语言实现选择结构时&#xff0c;根据某种条件的成立与否而采用不同的程序段进行…

基于nodejs+vue的农产品销售管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

FortiGate 无线组网

无线管理与配置 FortiAP 连接 internal 接口之后自动获得 ip 地址&#xff1a;192.168.1.xxx/24在 FortiGate 中创建 SSIDFortiGate 自动发现 FortiAP&#xff0c;将 FortiAP 添加到 FortiGate将 SSID 和 FortiAP 关联创建防火墙策略 下面我们就来一起看看在 FortiGate 中该如…

ModbusTCP通讯错误的排查

Modbus是一种由MODICON公司开发的工业现场总线协议标准&#xff0c;是一项应用层报文传输协议。该协议用于传输数字和模拟变量[1]。有关该协议的报文具体格式&#xff0c;以及一些基本概念&#xff0c;见[1]。 本文以一个例子&#xff0c;阐述当ModbusTCP通讯出现错误的时候&a…

开源鸿蒙OpenHarmony系统更换开机Logo方法,瑞芯微RK3566鸿蒙开发板

本文适用于开源鸿蒙OpenHarmony系统更换开机Logo&#xff0c;本次使用的是触觉智能的Purple Pi OH鸿蒙开源主板&#xff0c;搭载了瑞芯微RK3566芯片&#xff0c;类树莓派设计&#xff0c;是Laval官方社区主荐的一款鸿蒙开发主板。 介绍 OpenHarmony的品牌标志、版本信息、项目…

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python 数据分析 可视化大屏 附源码 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

探索EasyCVR视频融合平台:在视频编解码与转码领域的灵活性优势

随着视频监控技术的飞速发展&#xff0c;各类应用场景对视频数据的处理需求日益复杂多样。从公共安全到智慧城市&#xff0c;再到工业监控&#xff0c;高效、灵活的视频处理能力成为衡量视频融合平台性能的重要标准。在众多解决方案中&#xff0c;EasyCVR视频融合平台凭借其在视…

大觅网之自动化部署(Automated Deployment of Da Mi Network)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

音视频整体解码流程和同步流程

目录 1. 整体解码流程1. 初始化 FFmpeg2. 打开媒体文件3. 查找解码器4. 打开解码器5. 读取和解码数据6. 处理解码后的帧7. 释放资源 2. 音视频同步整体流程1. 解复用媒体流2. 解码3. 以音频为时钟源进行音视频同步的策略4. 缓冲区设计 现在先说大体流程&#xff0c;不分析代码 …

使用python爬取豆瓣网站?如何简单的爬取豆瓣网站?

1.对python爬虫的看法 首先说说我对python的看法&#xff0c;我的专业是大数据&#xff0c;我从事的工作是java开发&#xff0c;但是在工作之余&#xff0c;我对python又很感兴趣&#xff0c;因为我觉得python是一门很好的语言&#xff0c;第一&#xff1a;它可以用来爬取数据…

如何使用 Rust 框架进行 RESTful API 的开发?

一、RESTful API 的开发 使用 Rust 框架进行 RESTful API 开发&#xff0c;你可以选择多种流行的 Rust Web 框架&#xff0c;如 Actix-web、Rocket、Warp 和 Tide 等。以下是使用这些框架进行 RESTful API 开发的基本步骤和概念&#xff1a; 选择框架&#xff1a;根据项…

探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾

上周六&#xff0c;第二十一期「Data Infra 研究社」在线上与大家相见。活动邀请到了西门子数据分析师陈砚林与 Databend 联合创始人王吟&#xff0c;为我们带来了一场关于 Snowflake 和 Databend 的技术探索。Snowflake&#xff0c;这个市值曾超过 700 亿美元的云原生数据仓库…

李宏毅机器学习2023-HW10-Adversarial Attack

文章目录 TaskBaselineFGSM (Fast Gradient Sign Method (FGSM)I-FGSM(Iterative Fast Gradient Sign Method)MI-FGSM(Momentum Iterative Fast Gradient Sign Method)M-DI2-FGSM(Diverse Input Momentum Iterative Fast Gradient Sign Method) Reportfgsm attackJepg Compress…

性能优化与资源管理:优化Selenium脚本的执行效率,合理管理浏览器实例和系统资源

目录 引言 一、Selenium基础与常用方法 1.1 Selenium简介 1.2 Selenium基础用法 二、Selenium性能优化技巧 2.1 使用WebDriverWait实现显式等待 2.2 启用无头模式 2.3 设置合理的页面加载策略 2.4 禁用图片和JavaScript加载 2.5 优化元素定位 2.6 合理使用隐式等待和…

从0开始linux(5)——vim

欢迎来到博主的专栏&#xff1a;从0开始linux 博主ID&#xff1a;代码小豪 文章目录 vim的多种模式底行模式命令命令模式视块模式&#xff08;visual block&#xff09; vim的配置 vim是linux系统的文本编辑器。就像windows的记事本一样。 使用vim指令可以使用vim打开一个文本文…

JavaWeb美食推荐管理系统

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 spring-mybatis.xml3.5 spring-mvc.xml3.5 login.jsp 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优…