[路飞]_leetcode-215-数组中的第K个最大元素

简介: leetcode-215-数组中的第K个最大元素

网络异常,图片无法展示
|


[题目地址][B站地址]


给定整数数组 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
复制代码


提示:


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


sort 排序


本题要我们返回数组中第 k 大的值,最简单直接的方法就是将数组进行降序排列,然后返回第 k 个元素即可


代码如下:


var findKthLargest = function(nums, k) {
  // 降序排序
  nums.sort((a,b) => b-a);
  // 返回排序后第k个元素
  return nums[k-1]
};
复制代码


小顶堆


涉及到维护前 k 个最值的问题,都可以通过堆来解题


本题要维护的是前 k 个最大值,所以我们可以通过小顶堆来维护前 k 个最大值


最后堆顶元素就是第 k 个最大值


代码如下:


// 小顶堆
class MinHeap {
  constructor(k){
    this.arr = [];
    this.size = 0;
    this.max = k;
  }
  // 插入操作
  push(val){
    this.arr.push(val);
    this.size++;
    // 自下向上平衡调整
    if(this.size>1){
      let cur = this.size-1,
      parent = (cur-1)>>1;
      while(cur>0&&this.arr[cur]<this.arr[parent]){
        [this.arr[parent],this.arr[cur]] =
        [this.arr[cur],this.arr[parent]]
        cur = parent,parent = (cur-1)>>1;
      }
    }
    // 如果堆中元素数量超过K个,弹出堆顶元素
    if(this.size>this.max) this.pop();
  }
  // 弹出操作
  pop(){
    this.arr[0] = this.arr.pop();
    this.size--;
    // 自上向下平衡调整
    let cur = 0,
    childl = 1,childr = 2;
    while(
      (childl<this.size&&this.arr[childl]<this.arr[cur]) ||
      (childr<this.size&&this.arr[childr]<this.arr[cur])
    ){
      if(childr<this.size&&this.arr[childr]<this.arr[childl]){
        [this.arr[cur],this.arr[childr]] =
        [this.arr[childr],this.arr[cur]]
        cur = childr
      }else{
        [this.arr[cur],this.arr[childl]] =
        [this.arr[childl],this.arr[cur]]
        cur = childl
      }
      childl = cur*2+1,childr = cur*2+2;
    }
  }
  // 返回堆顶元素
  top(){
    return this.arr[0]
  }
}
var findKthLargest = function(nums, k) {
  // 创建小顶堆实例
  const heap = new MinHeap(k);
  // 循环输入数组
  for(let i = 0;i<nums.length;i++){
    // 当堆中数量小于k或者当前元素大于堆顶元素的时候,将当前元素插入堆中
    if(heap.size<k||nums[i]>heap.top()){
      heap.push(nums[i])
    }
  }
  // 返回堆顶元素
  return heap.top();
};
复制代码


至此我们就完成了 leetcode-215-数组中的第K个最大元素


如有任何问题或建议,欢迎留言讨论!

相关文章
|
11月前
【力扣】-- 移除链表元素
【力扣】-- 移除链表元素
124 1
|
5月前
|
机器学习/深度学习 存储 算法
【LeetCode 热题100】347:前 K 个高频元素(详细解析)(Go语言版)
这篇文章详细解析了力扣热题 347——前 K 个高频元素的三种解法:哈希表+小顶堆、哈希表+快速排序和哈希表+桶排序。每种方法都附有清晰的思路讲解和 Go 语言代码实现。小顶堆方法时间复杂度为 O(n log k),适合处理大规模数据;快速排序方法时间复杂度为 O(n log n),适用于数据量较小的场景;桶排序方法在特定条件下能达到线性时间复杂度 O(n)。文章通过对比分析,帮助读者根据实际需求选择最优解法,并提供了完整的代码示例,是一篇非常实用的算法学习资料。
345 90
|
3月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
136 1
|
11月前
【LeetCode 27】347.前k个高频元素
【LeetCode 27】347.前k个高频元素
106 0
|
11月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
82 4
|
11月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
94 0
Leetcode第三十三题(搜索旋转排序数组)
|
11月前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
181 0
|
11月前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
76 0
|
11月前
【LeetCode 06】203.移除链表元素
【LeetCode 06】203.移除链表元素
84 0
|
11月前
【LeetCode-每日一题】移除元素
【LeetCode-每日一题】移除元素
83 0

热门文章

最新文章