尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
JavaScript 找出数组中最大的 k 个元素(Find k largest elements in an array)
如果您喜欢此文章请收藏、点赞、评论谢谢祝您快乐每一天。给定一个数组arr[]和一个整数k任务是找出给定数组中最大的 k 个元素。输出数组中的元素应按降序排列。例如输入[1, 23, 12, 9, 30, 2, 50]k 3输出[ 50, 30, 23]输入[11, 5, 12, 9, 44, 17, 2]k 2输出[ 44, 17]【朴素方法】使用排序其思路是将输入数组按降序排列使数组中的前k 个元素成为最大的k 个元素。// JavaScript program to find k largest elements// in an array using sortingfunction kLargest(arr, k) {// sort the given array in descending orderarr.sort((a, b) b - a);// store the first k elements in result arraylet res arr.slice(0, k);return res;}// Driver Codeconst arr [1, 23, 12, 9, 30, 2, 50];const k 3;const res kLargest(arr, k);console.log(res.join( ));输出50 30 23时间复杂度O(n * log n)辅助空间O(1)【预期方法】使用优先级队列最小堆其思路是在遍历数组的过程中每一步都记录下最大的 k 个元素。为此我们使用最小堆。首先将初始的 k 个元素插入最小堆。之后对于每个后续元素我们将其与堆顶元素进行比较。由于最小堆的堆顶元素是这 k 个元素中最小的如果当前元素大于堆顶元素则意味着堆顶元素不再是最大的 k 个元素之一。在这种情况下我们移除堆顶元素并插入更大的元素。完成整个遍历后堆将恰好包含数组中最大的 k 个元素。// JavaScript program to find the k largest elements in the// array using min heapclass MinHeap {constructor() {this.heap [];}// Swap two elements in the heapswap(i, j) {[this.heap[i], this.heap[j]] [this.heap[j], this.heap[i]];}// Heapify up to maintain min heap propertyheapifyUp() {let index this.heap.length - 1;while (index 0) {let parentIndex Math.floor((index - 1) / 2);if (this.heap[parentIndex] this.heap[index]) break;this.swap(parentIndex, index);index parentIndex;}}// Heapify down to maintain min heap propertyheapifyDown() {let index 0;while (2 * index 1 this.heap.length) {let leftChild 2 * index 1;let rightChild 2 * index 2;let smallest leftChild;if (rightChild this.heap.length this.heap[rightChild] this.heap[leftChild]) {smallest rightChild;}if (this.heap[index] this.heap[smallest]) break;this.swap(index, smallest);index smallest;}}// Insert element into the min heappush(val) {this.heap.push(val);this.heapifyUp();}// Remove and return the top element (smallest)pop() {if (this.heap.length 1) return this.heap.pop();let min this.heap[0];this.heap[0] this.heap.pop();this.heapifyDown();return min;}// Get the top element (smallest)top() {return this.heap[0];}// Check if the heap is emptyempty() {return this.heap.length 0;}}// Function to find the k largest elements in the arrayfunction kLargest(arr, k) {// Min Priority Queue (Min-Heap) with first k// elements of the arraylet minH new MinHeap();for (let i 0; i k; i) {minH.push(arr[i]);}// Traverse n - k elementsfor (let i k; i arr.length; i) {// If the top of heap is less than the arr[i]// then remove top element and insert arr[i]if (minH.top() arr[i]) {minH.pop();minH.push(arr[i]);}}let res [];// Min heap will contain only k// largest elementswhile (!minH.empty()) {res.push(minH.pop());}// Reverse the result array, so that all// elements are in decreasing orderres.reverse();return res;}// Driver Codelet arr [1, 23, 12, 9, 30, 2, 50];let k 3;let res kLargest(arr, k);console.log(res.join( ));输出50 30 23时间复杂度O(n * log k)由于构建堆需要线性时间因此该方案可在 O(k (nk) Log K) 时间完成。辅助空间O(k)注意JavaScript 原生实现似乎不支持最小堆因此建议使用快速选择实现。【替代方法】使用快速选择算法其思路是利用快速排序的分区步骤在不重新排序整个数组的情况下找到数组中最大的 k 个元素。c 快速排序c 快速排序QuickSort_快速排序c代码-CSDN博客c语言 快速排序c语言 快速排序QuickSort_分区操作选择最后一个元素作为基准 c语言-CSDN博客python 快速排序Python 快速排序QuickSort_python实现快速排序-CSDN博客c# 快速排序C# 快速排序QuickSort-CSDN博客java 快速排序java 快速排序QuickSort_quicksort java-CSDN博客PHP 快速排序PHP 快速排序QuickSort-CSDN博客JavaScript快速排序JavaScript 快速排序QuickSort-CSDN博客在按降序对元素进行排序时分区步骤会重新排列元素将所有大于或等于选定基准元素通常是最后一个元素的元素放在基准元素的左侧将所有小于基准元素的元素放在基准元素的右侧并将基准元素置于其正确的排序位置。每次分区后我们将数组左侧部分包含所有大于或等于基准元素的元素的元素个数与 k进行比较左侧元素个数 k这意味着左侧部分的所有元素包括枢轴元素都是最大的 k 个元素。左侧元素个数 k这意味着最大的 k 个元素只存在于左侧子数组中因此我们在左侧子数组中递归搜索。左侧元素个数小于 k这意味着最大的 k 个元素包含了数组左侧的全部元素以及右侧的部分元素。因此我们将 k 减去左侧已覆盖的元素个数然后在右侧子数组中搜索。// JavaScript program to find the k largest elements in the array// using partitioning step of quick sort// Function to partition the array around a pivotfunction partition(arr, left, right) {// Last element is chosen as a pivot.let pivot arr[right];let i left;for (let j left; j right; j) {// Elements greater than or equal to pivot are// placed in the left part of pivotif (arr[j] pivot) {[arr[i], arr[j]] [arr[j], arr[i]];i;}}[arr[i], arr[right]] [arr[right], arr[i]];// The correct sorted position of the pivotreturn i;}function quickSelect(arr, left, right, k) {if (left right) {let pivotIdx partition(arr, left, right);// Count of all elements in the left partlet leftCnt pivotIdx - left 1;// If leftCnt is equal to k, then the first// k element of the array will be largestif (leftCnt k)return;// Search in the left subarrayif (leftCnt k)quickSelect(arr, left, pivotIdx - 1, k);// Reduce the k by number of elements already covered// and search in the right subarrayelsequickSelect(arr, pivotIdx 1, right, k - leftCnt);}}function kLargest(arr, k) {quickSelect(arr, 0, arr.length - 1, k);// First k elements of the array, will be the largestlet res arr.slice(0, k);// Sort the first k elements in descending orderres.sort((a, b) b - a);return res;}// Driver Codeconst arr [1, 23, 12, 9, 30, 2, 50];const k 3;const res kLargest(arr, k);console.log(res.join( ));输出50 30 23时间复杂度最坏情况下为O(n² )平均情况下为 O(n)。辅助空间O(n)如果您喜欢此文章请收藏、点赞、评论谢谢祝您快乐每一天。
RELATED

相关推荐

八月瓜科技专利API接口打通知产全链路

八月瓜科技专利API接口打通知产全链路

在企业研发越来越讲求效率的当下,知识产权服务已经不再只是申请专利、注册商标这么简单。对很多企业来说,真正重要的是把技术情报获取、研发立项判断、专利检索分析、申请布局、风险预警、成果运营、资产管理这些环节串起来,形成一套可持续运…

📅 2026/10/12 6:53:51
核心调用链的拆分

核心调用链的拆分

核心调用链的拆分 “超时重试怎样才不放大故障”首先要落到可观察、可回滚的工程动作上。本文从配置、调用链和运行指标三个层面梳理判断方法,重点说明应先收集什么证据、怎样做小范围验证,以及何时应停止扩张改动。 文中出现的故障现象、容量规模、延迟…

📅 2026/10/17 9:32:40
苦于没选题、原创难产的内容创业者!全套对标克隆实操,靠工具箱轻松复刻爆款

苦于没选题、原创难产的内容创业者!全套对标克隆实操,靠工具箱轻松复刻爆款

做自媒体矩阵、日常发笔记的小伙伴,应该都有过这种困扰:自己凭空写文案、搭结构,熬半天做出来的内容没流量、没互动,反观同行笔记条条爆火,却不知道别人的流量逻辑到底在哪。很多新手不敢对标爆款,总觉得模…

📅 2026/10/13 8:54:47
MORE NEWS

更多资讯

📰

系统思考与艺术思维的融合实践指南

1. 系统思考的本质与价值 系统思考是一种超越线性思维的认知方式,它要求我们跳出局部视角,将事物视为相互关联的整体。这种思维方式最早可以追溯到20世纪40年代的控制论研究,后来在管理学、生态学等领域得到广泛应用。 系统思考的核心在于识…

📰

React企业级前端工程化实践:从技术选型到落地优化

在我经手过的几个前端项目里,代号 REA(React Enterprise Application)算是最特殊的一个。它不是一个业务系统,也不是某个现成框架,而是为一支研发团队专门定制的前端基础工程——你可以把它理解成一套"开箱即用的…

📰

多智能体协作系统设计:从角色定义到调度器实现

1. 从“agency-agents”这个标题说起:它到底想解决什么问题第一次看到“agency-agents”这个标题,我脑子里蹦出来的第一反应是:这大概率是一个围绕“代理”和“智能体”两个概念做文章的项目。拆开来看,“agency”在英文里既可以指…

📰

Git提交次数统计技巧与应用场景

1. 为什么需要统计Git提交次数 在日常开发工作中,我们经常需要统计某个时间段内的代码提交情况。这个需求看似简单,但背后却有着多重实用价值: 项目进度评估 :通过统计团队成员在特定时间段(如冲刺周期)的…

📰

推理模型与通用模型选型、提示语策略与需求表达公式

简介:《DeepSeek从入门到精通(20250204)》面向AI初学者、内容创作者、开发者及企业应用者,围绕DeepSeek是什么、能做什么、如何用好搭建系统学习框架,帮助读者从基础认知走向提示语设计与模型选择。压缩包共1个PDF文件…

📰

数据库触发器实现复杂业务级联删除的最佳实践

1. 复杂业务关联删除的挑战与常规方案对比在企业级数据库应用中,数据表之间的关联关系往往错综复杂。以电商系统为例,一个简单的订单删除操作可能涉及订单主表、订单明细表、支付记录表、物流信息表等十余张关联表。传统的处理方式通常存在以下痛点&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬