学习记录:js算法(六十六):数组中的第K个最大元素

文章目录

    • 数组中的第K个最大元素
      • 思路一
      • 思路二

数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

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

思路一

function findKthLargest(nums, k) {function partition(left, right, pivotIndex) {const pivotValue = nums[pivotIndex];// 将基准元素交换到数组末尾[nums[pivotIndex], nums[right]] = [nums[right], nums[pivotIndex]];let storeIndex = left;for (let i = left; i < right; i++) {if (nums[i] < pivotValue) {[nums[storeIndex], nums[i]] = [nums[i], nums[storeIndex]];storeIndex++;}}// 将基准元素放到正确的位置[nums[right], nums[storeIndex]] = [nums[storeIndex], nums[right]];return storeIndex;}function quickSelect(left, right, kSmallest) {if (left === right) return nums[left];let pivotIndex = Math.floor(Math.random() * (right - left + 1)) + left;pivotIndex = partition(left, right, pivotIndex);if (kSmallest === pivotIndex) {return nums[kSmallest];} else if (kSmallest < pivotIndex) {return quickSelect(left, pivotIndex - 1, kSmallest);} else {return quickSelect(pivotIndex + 1, right, kSmallest);}}// 调整k为基于0的索引return quickSelect(0, nums.length - 1, nums.length - k);
}

讲解
要找到数组中第 > 个最大的元素,且要求时间复杂度为 O(n),我们可以使用快速选择算法,这是一种基于快速排序的选择算法变种,用于找到未排序数组中的第 > 个元素,而无需完全排序数组。

  1. 选择基准:从数组中随机选择一个元素作为基准元素,或者选择数组的第一个元> 素、最后一个元素等作为基准。
  2. 分区操作:将数组分为两部分,一部分包含所有不大于基准的元素,另一部分包含所有大于基准的元素。这个操作结束后,基准元素会处于它在排序后数组中的最终位置。同时,我们也会得到基准元素在排序后数组中的索引。
  3. 根据基准索引判断:
    ● 基准索引等于目标索引:如果 pivotIndex 等于 kSmallest (即 nums.length - k ),这意味着基准元素恰好是我们要找的第k个最大元素,因为它在排序后的数组中位于正确的位置。此时,直接返回基准元素的值。
    ● 基准索引小于目标索引:如果 pivotIndex 小于 kSmallest ,说明我们要找的第 k 个最大元素一定在基准元素的右侧(不包括基准元素本身)。因此,我们递归地在右半边的子数组中继续寻找。
    ● 基准索引大于目标索引:如果 pivotIndex 大于 kSmallest ,说明我们要找的第 k 个最大元素一定在基准元素的左侧(包括基准元素)。因此,我们递归地在左半边的子数> 组中继续寻找。
  4. 递归或迭代:重复上述过程,直到找到第 k 大的元素。

思路二

function heapify(arr, n, i) {let smallest = i; // 初始化根节点为最小值let left = 2 * i + 1; // 左子节点let right = 2 * i + 2; // 右子节点// 如果左子节点存在且小于根节点,则更新smallestif (left < n && arr[left] < arr[smallest])smallest = left;// 如果右子节点存在且小于当前smallest,则更新smallestif (right < n && arr[right] < arr[smallest])smallest = right;// 如果smallest不是根节点,则交换它们并继续heapifyif (smallest !== i) {[arr[i], arr[smallest]] = [arr[smallest], arr[i]]; // 交换heapify(arr, n, smallest); // 递归heapify受影响的子树}
}function buildMinHeap(arr) {const n = arr.length;// 从最后一个非叶子节点开始heapifyfor (let i = Math.floor(n / 2) - 1; i >= 0; i--) {heapify(arr, n, i);}
}function findKthLargest(nums, k) {// 创建一个大小为k的最小堆let minHeap = nums.slice(0, k);buildMinHeap(minHeap); // 构建最小堆// 遍历剩余元素for (let i = k; i < nums.length; i++) {if (nums[i] > minHeap[0]) {minHeap[0] = nums[i]; // 替换最小元素heapify(minHeap, k, 0); // 重新heapify}}// 最终堆顶元素就是第k大的元素return minHeap[0];
}

讲解

  1. 初始化最小堆:从数组的前k个元素开始,构建一个最小堆。这个堆将保持数组中最大的 k 个元素。
  2. 遍历剩余元素:遍历数组中剩余的元素。对于每个元素,如果它比堆顶元素(堆中最小的元素)还要大,那么就用这个元素替换堆顶元素,并重新调整堆,确保堆的性质不变。
  3. 返回堆顶元素:当所有元素都处理完毕后,堆顶元素就是数组中第 k 大的元素,因为此时堆中保存的是最大的 k 个元素,堆顶元素是这 k 个元素中最小的,即第 k 大的元素。

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

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

相关文章

PPT怎么转成PDF?5个超简单转换方法,快来学(包靠谱)

PPT怎么转成PDF&#xff1f;PPT&#xff08;PowerPoint演示文稿&#xff09;是一种重要的文件格式&#xff0c;通过它&#xff0c;我们能够直观地呈现信息、分享观点以及进行商务演示。然而在有些时候&#xff0c;我们需要将PPT文件转化为PDF格式&#xff0c;以便于分享、打印或…

基于AutoGen+Ollama+Litellm构建知识库问答系统

目录 1 背景 1.1 AutoGen介绍 1.2 Ollama介绍 1.3 Litellm介绍 2 部署搭建 2.1 AutoGen + Ollama + Litellm环境搭建 2.2 基于AutoGen构建多智能体对话 2.3 基于AutoGen构建知识库问答系统 1 背景 之前已经基于Llama+LangChain构建了知识库问答系统。但是随着智能体的…

系统设计中的消息队列

在复杂的系统设计中&#xff0c;消息队列是一种不可或缺的技术组件&#xff0c;它在提升系统灵活性、可扩展性和可靠性方面发挥着重要作用。本文将详细介绍消息队列的基本概念、工作原理、主要优势以及在系统设计中的具体应用。 一、消息队列的基本概念 消息队列&#xff08;…

基于PHP考研互助系统【附源码】

基于PHP考研互助系统 效果如下&#xff1a; 系统首页界面 用户注册界面 考研论坛页面 每日打卡页面 管理员登录主页面 管理员主界面 用户管理界面 备考经验界面 研究背景 近些年&#xff0c;随着中国经济发展&#xff0c;人民的生活质量逐渐提高&#xff0c;对网络的依赖性越…

软件Bug和缺陷的区别是什么?

前言 在任何软件生命周期中&#xff0c;软件缺陷的出现几乎是不可避免的。建立一套有效的缺陷管理流程的目的是为了减少软件缺陷出现的几率&#xff0c;并且大幅度降低由于软件缺陷带来的负面影响。对于缺陷管理流程的投资&#xff0c;可以大幅度的降低由于返工/修复缺陷导致的…

开源的介绍

文章目录 一、开源的定义二、开源的历史发展三、开源的优势3.1 **透明性**3.2 **社区贡献**3.3 **安全性**3.4 **快速迭代**3.5 **定制与扩展**3.6 **成本效益** 四、开源软件的挑战4.1 **维护问题**4.2 **技术支持**4.3 **学习曲线**4.4 **兼容性** 五、常见的开源软件和项目六…

模版和STL

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 前言 string是标准库中的一个类&#xff0c;它位于<string>头文件中。 这个类提…

大厂面试真题-说一下Kafka的分区再均衡机制

Kafka的分区再均衡机制是用于重新分配消费者组&#xff08;Consumer Group&#xff09;中消费者&#xff08;Consumer&#xff09;和分区&#xff08;Partition&#xff09;之间关系的机制。这种机制在消费者组内的消费者数量变化&#xff0c;或者消费者订阅的主题发生变化&…

Python基础:19、Python异常、模块与包

1&#xff09;python异常 什么是异常&#xff1a;异常就是程序运行的过程中出现了错误 bug是什么意思&#xff1a;bug就是指异常的意思&#xff0c;因为历史因为小虫子导致计算机失灵的案例&#xff0c;所以延续至今&#xff0c;bug就代表软件出现错误。 2&#xff09;异常的…

【Vue.js设计与实现】阅读笔记目录(持续更新)

文章目录 第一篇&#xff1a;框架设计概览第二篇&#xff1a;响应系统第三篇&#xff1a;渲染器第四篇&#xff1a;组件化第五篇&#xff1a;编译器第六篇&#xff1a;服务端渲染 第一篇&#xff1a;框架设计概览 【Vue.js设计与实现】第一篇&#xff1a;框架设计概览-阅读笔记…

gitlab的基本用法之创建用户和组

安装好gitlab后要做一些基本的创建 创建顺序&#xff1a;先创建组——再创建项目——最后创建用户项目、组、用户的关系&#xff1a;把创建的用户和项目加入组中&#xff0c;只有同一组的用户才能操作该组的项目。 一、创建群组 点击设置就可以看到刚才创建的组 二、创建项…

SpringCloudStream使用StreamBridge实现延时队列

利用RabbitMQ实现消息的延迟队列 一、安装RabbitMQ 1、安装rabbitmq 安装可以看https://blog.csdn.net/qq_38618691/article/details/118223851,进行安装。 2、安装插件 安装完毕后,exchange是不支持延迟类型的,需要手动安装插件,需要和安装的rabbitmq版本一致 https:…

可以在桌面上用的倒计时提醒app下载

在忙碌的工作日常中&#xff0c;我们常常需要记住各种截止日期和重要事件。为了确保这些任务按时完成&#xff0c;一款桌面倒计时提醒应用变得尤为重要。想象一下&#xff0c;当你在电脑桌面上就能清晰地看到剩余时间&#xff0c;这无疑会增加你的工作效率和紧迫感。 敬业签就…

红日安全vulnstack (二)

目录 环境搭建 网卡设置 修改Kali网段 IP 分布 WEB渗透 Weblogin服务开启 漏洞扫描 CVE工具利用 MSF上线 内网渗透 域内信息收集 凭证横向移动 权限维持 黄金票据 参考文章 https://www.cnblogs.com/bktown/p/16904232.htmlhttps://blog.csdn.net/m0_75178803/ar…

好用的python相关的AI工具Bito介绍

插件名称&#xff1a;Bito 好用的python相关的AI工具Bito介绍 step 1:点插件step 2&#xff1a;搜索bito并安装step3 &#xff1a;需要登录&#xff0c;要有真实邮箱&#xff0c;按步骤走就行&#xff0c;完后就可以使用 step 1:点插件 step 2&#xff1a;搜索bito并安装 step3…

关于新国标强制电动车应内置北斗定位模块的规定有哪些?附北斗定位芯片对比参数

关于新国标要求电动自行车内置的北斗定位功能&#xff0c;需要符合以下几点&#xff1a; 支持UART或SPI接口至少支持接收处理北斗B1C和B2a信号具备定位信息的采集、存储和发送功能&#xff08;其中定位信息包括&#xff1a;经度、纬度、速度、定位时间&#xff09;具备采集、存…

专题:回溯算法专题(已完结)

回溯四部曲 1.确定是否需要返回值(和题目的递归函数函数是否有返回值无关) 2.确定遍历顺序&#xff08;有返回值接的需要接住&#xff09; 3.确定结束条件&#xff08;注意是否存在中途直接return&#xff09; 4.确定单层循环逻辑 1.组合 class Solution {vector<vector&l…

1.项目初始化

目录 1.相关联的数据库表 2.使用gorm操作数据库 使用gen生成model和对数据库的操作 3.使用viper进行配置管理 读取配置文件 进行热更新 4.使用Pflag来进行命令行参数解析 5.使用日志slog 日志轮转与切割功能 6.错误码和http返回格式标准化 提供错误码 提供错误类型…

vue3中swiper11的使用

Swiper官网 vue中使用方法 我使用的是 “vue”: “3.5.11”&#xff0c;swiper版本为 “swiper”: “11.1.14”&#xff0c; “less”: “4.2.0” 1. 属性介绍 属性名作用slidesPerView设置slider容器能够同时显示的slides数量(carousel模式)。可以设置为数字&#xff08;小…

立志最细,FreeRtos中的任务通知(Task Notification)详解!!!

目录 基本概念 任务通知特性 函数原型 简化版函数 专业版函数 前言&#xff1a;本篇参考&#xff0c;韦东山开发文档&#xff0c;连接放在最后 基本概念 在FreeRtos操作系统里面&#xff0c;任务通知(Task Notification)是一种专门用在任务间的任务通信机制&#xff0c;被…