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

153 阅读1分钟

题目介绍

给定整数数组 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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/kt… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

根据题意是要找到数组中的,最大k个数,是个最值问题。所以用堆解决,实现一个小顶堆,遍历数组,将数组的元素压入堆中,如果堆的size大于k,弹出元素,最后堆顶的元素的就是第k个最大值

代码

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number}
 */
class Heap {
  constructor() {
    this.data = []
  }
  // 向下调
  shiftDown(ind = 0) {
    let n = this.size() - 1
    while (ind * 2 + 1 <= n) {
      let tmp = ind
      // 小顶堆是用大于号 this.data[tmp] > this.data[ind * 2 + 1], 大顶堆小于号 this.data[tmp] < this.data[ind * 2 + 1]
      if (this.data[tmp] > this.data[ind * 2 + 1]) tmp = ind * 2 + 1
      if (ind * 2 + 2 <= n && this.data[tmp] > this.data[ind * 2 + 2])
        tmp = ind * 2 + 2
      if (tmp === ind) break
      this.data[tmp] = [this.data[ind], (this.data[ind] = this.data[tmp])][0]
      ind = tmp
    }
  }
  // 向上调整
  shiftUp(idx) {
    let pIdx = null
    while (
      ((pIdx = Math.floor((idx - 1) / 2)),
      // 小顶堆是用大于号 this.data[pIdx] > this.data[idx], 大顶堆用小于号this.data[pIdx] < this.data[idx]
      idx && this.data[pIdx] > this.data[idx])
    ) {
      this.data[pIdx] = [this.data[idx], (this.data[idx] = this.data[pIdx])][0]
      idx = pIdx
    }
  }
  push(val) {
    this.data.push(val)
    this.shiftUp(this.size() - 1)
  }
  pop() {
    if (this.size() === 0) return
    if (this.size() === 1) {
      return this.data.pop()
    }
    this.data[0] = this.data.pop()
    this.shiftDown(0)
  }
  top() {
    return this.data[0]
  }
  size() {
    return this.data.length
  }
}
var findKthLargest = function(nums, k) {
    // nums = nums.sort((a, b) => b - a)
    // return nums[k - 1]
    let h = new Heap()
    for (let val of nums) {
        h.push(val)
        if (h.size() > k) {
            h.pop()
        }
    }
    return h.top()
};