layout: posttitle: PHP 计算数据流中的第K大的元素
subtitle: PHP 计算数据流中的第K大的元素
date: 2020-05-18
author: he xiaodong
header-img: img/default-post-bg.jpg
catalog: true
tags:
- Go
- PHP
- LeetCode
- 数据流中的第K大元素

用队列实现栈

设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。

你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。

示例:

  1. int k = 3;
  2. int[] arr = [4,5,8,2];
  3. KthLargest kthLargest = new KthLargest(3, arr);
  4. kthLargest.add(3); // returns 4
  5. kthLargest.add(5); // returns 5
  6. kthLargest.add(10); // returns 5
  7. kthLargest.add(9); // returns 8
  8. kthLargest.add(4); // returns 8

说明:
你可以假设 nums 的长度≥ k-1 且k ≥ 1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream

理解题意

最开始没理解这道题,读了几遍明白了,k 是指定的位置,然后一组数,按从大到小排列,然后返回第 k 个元素,最基础考虑是每次 add 都需要一次排序,然后重新查找第 k 个元素的值,例如 5,3,6,2 四个数,倒叙之后是6,5,3,2,则 k = 2 的情况下,返回5,然后 add 1的情况,追加在最末尾,不影响结果,add 7 的情况,追加在最开头,返回值变成 6。

解题思路

直接使用最小堆,堆的大小为 k,这样保证空间占用最小,最小堆的根节点是就是最小值,也是我们想要的结果。PHP 的 SPL 标准库是有最小堆这个库,直接在代码中继承 SplMinHeap 。

PHP 实现

  1. class KthLargest extends SplMinHeap {
  2. /**
  3. * @param Integer $k
  4. * @param Integer[] $nums
  5. */
  6. static $nums;
  7. public $k;
  8. function __construct($k, $nums) {
  9. $this->k = $k;
  10. // 遍历初始化数组,分别插入堆中
  11. foreach ($nums as $v) {
  12. $this->add($v);
  13. }
  14. }
  15. /**
  16. * @param Integer $val
  17. * @return Integer
  18. */
  19. function add($val) {
  20. // 维持堆的大小为k,当堆还未满时,插入数据。
  21. if ($this->count() < $this->k) {
  22. $this->insert($val);
  23. } elseif ($this->top() < $val) {
  24. // 当堆满的时候,比较要插入元素和堆顶元素大小。大于堆顶的插入。堆顶移除。
  25. $this->extract();
  26. $this->insert($val);
  27. }
  28. return $this->top();
  29. }
  30. }
  31. /**
  32. * Your KthLargest object will be instantiated and called as such:
  33. * $obj = KthLargest($k, $nums);
  34. * $ret_1 = $obj->add($val);
  35. */

最后恰饭 阿里云全系列产品/短信包特惠购买 中小企业上云最佳选择 阿里云内部优惠券