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大的元素。
示例:
int k = 3;int[] arr = [4,5,8,2];KthLargest kthLargest = new KthLargest(3, arr);kthLargest.add(3); // returns 4kthLargest.add(5); // returns 5kthLargest.add(10); // returns 5kthLargest.add(9); // returns 8kthLargest.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 实现
class KthLargest extends SplMinHeap {/*** @param Integer $k* @param Integer[] $nums*/static $nums;public $k;function __construct($k, $nums) {$this->k = $k;// 遍历初始化数组,分别插入堆中foreach ($nums as $v) {$this->add($v);}}/*** @param Integer $val* @return Integer*/function add($val) {// 维持堆的大小为k,当堆还未满时,插入数据。if ($this->count() < $this->k) {$this->insert($val);} elseif ($this->top() < $val) {// 当堆满的时候,比较要插入元素和堆顶元素大小。大于堆顶的插入。堆顶移除。$this->extract();$this->insert($val);}return $this->top();}}/*** Your KthLargest object will be instantiated and called as such:* $obj = KthLargest($k, $nums);* $ret_1 = $obj->add($val);*/
